

<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="zh-CN" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="zh-CN" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  <title>logging &mdash; wukong-robot 1.2.0 文档</title>
  

  
  
  
  

  
  <script type="text/javascript" src="../_static/js/modernizr.min.js"></script>
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
        <script type="text/javascript" src="../_static/jquery.js"></script>
        <script type="text/javascript" src="../_static/underscore.js"></script>
        <script type="text/javascript" src="../_static/doctools.js"></script>
        <script type="text/javascript" src="../_static/language_data.js"></script>
        <script type="text/javascript" src="../_static/translations.js"></script>
    
    <script type="text/javascript" src="../_static/js/theme.js"></script>

    

  
  <link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
  <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <link rel="index" title="索引" href="../genindex.html" />
    <link rel="search" title="搜索" href="../search.html" /> 
</head>

<body class="wy-body-for-nav">

   
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >
          

          
            <a href="../index.html" class="icon icon-home"> wukong-robot
          

          
          </a>

          
            
            
          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <!-- Local TOC -->
              <div class="local-toc"></div>
            
          
        </div>
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../index.html">wukong-robot</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="../index.html">Docs</a> &raquo;</li>
        
          <li><a href="index.html">模块代码</a> &raquo;</li>
        
      <li>logging</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
      </li>
    
  </ul>

  
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
  <h1>logging 源代码</h1><div class="highlight"><pre>
<span></span><span class="c1"># Copyright 2001-2016 by Vinay Sajip. All Rights Reserved.</span>
<span class="c1">#</span>
<span class="c1"># Permission to use, copy, modify, and distribute this software and its</span>
<span class="c1"># documentation for any purpose and without fee is hereby granted,</span>
<span class="c1"># provided that the above copyright notice appear in all copies and that</span>
<span class="c1"># both that copyright notice and this permission notice appear in</span>
<span class="c1"># supporting documentation, and that the name of Vinay Sajip</span>
<span class="c1"># not be used in advertising or publicity pertaining to distribution</span>
<span class="c1"># of the software without specific, written prior permission.</span>
<span class="c1"># VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING</span>
<span class="c1"># ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL</span>
<span class="c1"># VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR</span>
<span class="c1"># ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER</span>
<span class="c1"># IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT</span>
<span class="c1"># OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.</span>

<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Logging package for Python. Based on PEP 282 and comments thereto in</span>
<span class="sd">comp.lang.python.</span>

<span class="sd">Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved.</span>

<span class="sd">To use, simply &#39;import logging&#39; and log away!</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">import</span> <span class="nn">sys</span><span class="o">,</span> <span class="nn">os</span><span class="o">,</span> <span class="nn">time</span><span class="o">,</span> <span class="nn">io</span><span class="o">,</span> <span class="nn">traceback</span><span class="o">,</span> <span class="nn">warnings</span><span class="o">,</span> <span class="nn">weakref</span><span class="o">,</span> <span class="nn">collections</span>

<span class="kn">from</span> <span class="nn">string</span> <span class="k">import</span> <span class="n">Template</span>

<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;BASIC_FORMAT&#39;</span><span class="p">,</span> <span class="s1">&#39;BufferingFormatter&#39;</span><span class="p">,</span> <span class="s1">&#39;CRITICAL&#39;</span><span class="p">,</span> <span class="s1">&#39;DEBUG&#39;</span><span class="p">,</span> <span class="s1">&#39;ERROR&#39;</span><span class="p">,</span>
           <span class="s1">&#39;FATAL&#39;</span><span class="p">,</span> <span class="s1">&#39;FileHandler&#39;</span><span class="p">,</span> <span class="s1">&#39;Filter&#39;</span><span class="p">,</span> <span class="s1">&#39;Formatter&#39;</span><span class="p">,</span> <span class="s1">&#39;Handler&#39;</span><span class="p">,</span> <span class="s1">&#39;INFO&#39;</span><span class="p">,</span>
           <span class="s1">&#39;LogRecord&#39;</span><span class="p">,</span> <span class="s1">&#39;Logger&#39;</span><span class="p">,</span> <span class="s1">&#39;LoggerAdapter&#39;</span><span class="p">,</span> <span class="s1">&#39;NOTSET&#39;</span><span class="p">,</span> <span class="s1">&#39;NullHandler&#39;</span><span class="p">,</span>
           <span class="s1">&#39;StreamHandler&#39;</span><span class="p">,</span> <span class="s1">&#39;WARN&#39;</span><span class="p">,</span> <span class="s1">&#39;WARNING&#39;</span><span class="p">,</span> <span class="s1">&#39;addLevelName&#39;</span><span class="p">,</span> <span class="s1">&#39;basicConfig&#39;</span><span class="p">,</span>
           <span class="s1">&#39;captureWarnings&#39;</span><span class="p">,</span> <span class="s1">&#39;critical&#39;</span><span class="p">,</span> <span class="s1">&#39;debug&#39;</span><span class="p">,</span> <span class="s1">&#39;disable&#39;</span><span class="p">,</span> <span class="s1">&#39;error&#39;</span><span class="p">,</span>
           <span class="s1">&#39;exception&#39;</span><span class="p">,</span> <span class="s1">&#39;fatal&#39;</span><span class="p">,</span> <span class="s1">&#39;getLevelName&#39;</span><span class="p">,</span> <span class="s1">&#39;getLogger&#39;</span><span class="p">,</span> <span class="s1">&#39;getLoggerClass&#39;</span><span class="p">,</span>
           <span class="s1">&#39;info&#39;</span><span class="p">,</span> <span class="s1">&#39;log&#39;</span><span class="p">,</span> <span class="s1">&#39;makeLogRecord&#39;</span><span class="p">,</span> <span class="s1">&#39;setLoggerClass&#39;</span><span class="p">,</span> <span class="s1">&#39;warn&#39;</span><span class="p">,</span> <span class="s1">&#39;warning&#39;</span><span class="p">,</span>
           <span class="s1">&#39;getLogRecordFactory&#39;</span><span class="p">,</span> <span class="s1">&#39;setLogRecordFactory&#39;</span><span class="p">,</span> <span class="s1">&#39;lastResort&#39;</span><span class="p">]</span>

<span class="k">try</span><span class="p">:</span>
    <span class="kn">import</span> <span class="nn">threading</span>
<span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span> <span class="c1">#pragma: no cover</span>
    <span class="n">threading</span> <span class="o">=</span> <span class="kc">None</span>

<span class="n">__author__</span>  <span class="o">=</span> <span class="s2">&quot;Vinay Sajip &lt;vinay_sajip@red-dove.com&gt;&quot;</span>
<span class="n">__status__</span>  <span class="o">=</span> <span class="s2">&quot;production&quot;</span>
<span class="c1"># The following module attributes are no longer updated.</span>
<span class="n">__version__</span> <span class="o">=</span> <span class="s2">&quot;0.5.1.2&quot;</span>
<span class="n">__date__</span>    <span class="o">=</span> <span class="s2">&quot;07 February 2010&quot;</span>

<span class="c1">#---------------------------------------------------------------------------</span>
<span class="c1">#   Miscellaneous module data</span>
<span class="c1">#---------------------------------------------------------------------------</span>

<span class="c1">#</span>
<span class="c1">#_startTime is used as the base when calculating the relative time of events</span>
<span class="c1">#</span>
<span class="n">_startTime</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>

<span class="c1">#</span>
<span class="c1">#raiseExceptions is used to see if exceptions during handling should be</span>
<span class="c1">#propagated</span>
<span class="c1">#</span>
<span class="n">raiseExceptions</span> <span class="o">=</span> <span class="kc">True</span>

<span class="c1">#</span>
<span class="c1"># If you don&#39;t want threading information in the log, set this to zero</span>
<span class="c1">#</span>
<span class="n">logThreads</span> <span class="o">=</span> <span class="kc">True</span>

<span class="c1">#</span>
<span class="c1"># If you don&#39;t want multiprocessing information in the log, set this to zero</span>
<span class="c1">#</span>
<span class="n">logMultiprocessing</span> <span class="o">=</span> <span class="kc">True</span>

<span class="c1">#</span>
<span class="c1"># If you don&#39;t want process information in the log, set this to zero</span>
<span class="c1">#</span>
<span class="n">logProcesses</span> <span class="o">=</span> <span class="kc">True</span>

<span class="c1">#---------------------------------------------------------------------------</span>
<span class="c1">#   Level related stuff</span>
<span class="c1">#---------------------------------------------------------------------------</span>
<span class="c1">#</span>
<span class="c1"># Default levels and level names, these can be replaced with any positive set</span>
<span class="c1"># of values having corresponding names. There is a pseudo-level, NOTSET, which</span>
<span class="c1"># is only really there as a lower limit for user-defined levels. Handlers and</span>
<span class="c1"># loggers are initialized with NOTSET so that they will log all messages, even</span>
<span class="c1"># at user-defined levels.</span>
<span class="c1">#</span>

<span class="n">CRITICAL</span> <span class="o">=</span> <span class="mi">50</span>
<span class="n">FATAL</span> <span class="o">=</span> <span class="n">CRITICAL</span>
<span class="n">ERROR</span> <span class="o">=</span> <span class="mi">40</span>
<span class="n">WARNING</span> <span class="o">=</span> <span class="mi">30</span>
<span class="n">WARN</span> <span class="o">=</span> <span class="n">WARNING</span>
<span class="n">INFO</span> <span class="o">=</span> <span class="mi">20</span>
<span class="n">DEBUG</span> <span class="o">=</span> <span class="mi">10</span>
<span class="n">NOTSET</span> <span class="o">=</span> <span class="mi">0</span>

<span class="n">_levelToName</span> <span class="o">=</span> <span class="p">{</span>
    <span class="n">CRITICAL</span><span class="p">:</span> <span class="s1">&#39;CRITICAL&#39;</span><span class="p">,</span>
    <span class="n">ERROR</span><span class="p">:</span> <span class="s1">&#39;ERROR&#39;</span><span class="p">,</span>
    <span class="n">WARNING</span><span class="p">:</span> <span class="s1">&#39;WARNING&#39;</span><span class="p">,</span>
    <span class="n">INFO</span><span class="p">:</span> <span class="s1">&#39;INFO&#39;</span><span class="p">,</span>
    <span class="n">DEBUG</span><span class="p">:</span> <span class="s1">&#39;DEBUG&#39;</span><span class="p">,</span>
    <span class="n">NOTSET</span><span class="p">:</span> <span class="s1">&#39;NOTSET&#39;</span><span class="p">,</span>
<span class="p">}</span>
<span class="n">_nameToLevel</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s1">&#39;CRITICAL&#39;</span><span class="p">:</span> <span class="n">CRITICAL</span><span class="p">,</span>
    <span class="s1">&#39;ERROR&#39;</span><span class="p">:</span> <span class="n">ERROR</span><span class="p">,</span>
    <span class="s1">&#39;WARN&#39;</span><span class="p">:</span> <span class="n">WARNING</span><span class="p">,</span>
    <span class="s1">&#39;WARNING&#39;</span><span class="p">:</span> <span class="n">WARNING</span><span class="p">,</span>
    <span class="s1">&#39;INFO&#39;</span><span class="p">:</span> <span class="n">INFO</span><span class="p">,</span>
    <span class="s1">&#39;DEBUG&#39;</span><span class="p">:</span> <span class="n">DEBUG</span><span class="p">,</span>
    <span class="s1">&#39;NOTSET&#39;</span><span class="p">:</span> <span class="n">NOTSET</span><span class="p">,</span>
<span class="p">}</span>

<div class="viewcode-block" id="getLevelName"><a class="viewcode-back" href="../logging.html#logging.getLevelName">[文档]</a><span class="k">def</span> <span class="nf">getLevelName</span><span class="p">(</span><span class="n">level</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Return the textual representation of logging level &#39;level&#39;.</span>

<span class="sd">    If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,</span>
<span class="sd">    INFO, DEBUG) then you get the corresponding string. If you have</span>
<span class="sd">    associated levels with names using addLevelName then the name you have</span>
<span class="sd">    associated with &#39;level&#39; is returned.</span>

<span class="sd">    If a numeric value corresponding to one of the defined levels is passed</span>
<span class="sd">    in, the corresponding string representation is returned.</span>

<span class="sd">    Otherwise, the string &quot;Level %s&quot; % level is returned.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="c1"># See Issues #22386 and #27937 for why it&#39;s this way</span>
    <span class="k">return</span> <span class="p">(</span><span class="n">_levelToName</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">level</span><span class="p">)</span> <span class="ow">or</span> <span class="n">_nameToLevel</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">level</span><span class="p">)</span> <span class="ow">or</span>
            <span class="s2">&quot;Level </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">level</span><span class="p">)</span></div>

<div class="viewcode-block" id="addLevelName"><a class="viewcode-back" href="../logging.html#logging.addLevelName">[文档]</a><span class="k">def</span> <span class="nf">addLevelName</span><span class="p">(</span><span class="n">level</span><span class="p">,</span> <span class="n">levelName</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Associate &#39;levelName&#39; with &#39;level&#39;.</span>

<span class="sd">    This is used when converting levels to text during message formatting.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">_acquireLock</span><span class="p">()</span>
    <span class="k">try</span><span class="p">:</span>    <span class="c1">#unlikely to cause an exception, but you never know...</span>
        <span class="n">_levelToName</span><span class="p">[</span><span class="n">level</span><span class="p">]</span> <span class="o">=</span> <span class="n">levelName</span>
        <span class="n">_nameToLevel</span><span class="p">[</span><span class="n">levelName</span><span class="p">]</span> <span class="o">=</span> <span class="n">level</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="n">_releaseLock</span><span class="p">()</span></div>

<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">sys</span><span class="p">,</span> <span class="s1">&#39;_getframe&#39;</span><span class="p">):</span>
    <span class="n">currentframe</span> <span class="o">=</span> <span class="k">lambda</span><span class="p">:</span> <span class="n">sys</span><span class="o">.</span><span class="n">_getframe</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span> <span class="c1">#pragma: no cover</span>
    <span class="k">def</span> <span class="nf">currentframe</span><span class="p">():</span>
        <span class="sd">&quot;&quot;&quot;Return the frame object for the caller&#39;s stack frame.&quot;&quot;&quot;</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">Exception</span>
        <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()[</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">tb_frame</span><span class="o">.</span><span class="n">f_back</span>

<span class="c1">#</span>
<span class="c1"># _srcfile is used when walking the stack to check when we&#39;ve got the first</span>
<span class="c1"># caller stack frame, by skipping frames whose filename is that of this</span>
<span class="c1"># module&#39;s source. It therefore should contain the filename of this module&#39;s</span>
<span class="c1"># source file.</span>
<span class="c1">#</span>
<span class="c1"># Ordinarily we would use __file__ for this, but frozen modules don&#39;t always</span>
<span class="c1"># have __file__ set, for some reason (see Issue #21736). Thus, we get the</span>
<span class="c1"># filename from a handy code object from a function defined in this module.</span>
<span class="c1"># (There&#39;s no particular reason for picking addLevelName.)</span>
<span class="c1">#</span>

<span class="n">_srcfile</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">normcase</span><span class="p">(</span><span class="n">addLevelName</span><span class="o">.</span><span class="vm">__code__</span><span class="o">.</span><span class="n">co_filename</span><span class="p">)</span>

<span class="c1"># _srcfile is only used in conjunction with sys._getframe().</span>
<span class="c1"># To provide compatibility with older versions of Python, set _srcfile</span>
<span class="c1"># to None if _getframe() is not available; this value will prevent</span>
<span class="c1"># findCaller() from being called. You can also do this if you want to avoid</span>
<span class="c1"># the overhead of fetching caller information, even when _getframe() is</span>
<span class="c1"># available.</span>
<span class="c1">#if not hasattr(sys, &#39;_getframe&#39;):</span>
<span class="c1">#    _srcfile = None</span>


<span class="k">def</span> <span class="nf">_checkLevel</span><span class="p">(</span><span class="n">level</span><span class="p">):</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">level</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
        <span class="n">rv</span> <span class="o">=</span> <span class="n">level</span>
    <span class="k">elif</span> <span class="nb">str</span><span class="p">(</span><span class="n">level</span><span class="p">)</span> <span class="o">==</span> <span class="n">level</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">level</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">_nameToLevel</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Unknown level: </span><span class="si">%r</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">level</span><span class="p">)</span>
        <span class="n">rv</span> <span class="o">=</span> <span class="n">_nameToLevel</span><span class="p">[</span><span class="n">level</span><span class="p">]</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">&quot;Level not an integer or a valid string: </span><span class="si">%r</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">level</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">rv</span>

<span class="c1">#---------------------------------------------------------------------------</span>
<span class="c1">#   Thread-related stuff</span>
<span class="c1">#---------------------------------------------------------------------------</span>

<span class="c1">#</span>
<span class="c1">#_lock is used to serialize access to shared data structures in this module.</span>
<span class="c1">#This needs to be an RLock because fileConfig() creates and configures</span>
<span class="c1">#Handlers, and so might arbitrary user threads. Since Handler code updates the</span>
<span class="c1">#shared dictionary _handlers, it needs to acquire the lock. But if configuring,</span>
<span class="c1">#the lock would already have been acquired - so we need an RLock.</span>
<span class="c1">#The same argument applies to Loggers and Manager.loggerDict.</span>
<span class="c1">#</span>
<span class="k">if</span> <span class="n">threading</span><span class="p">:</span>
    <span class="n">_lock</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">RLock</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span> <span class="c1">#pragma: no cover</span>
    <span class="n">_lock</span> <span class="o">=</span> <span class="kc">None</span>


<span class="k">def</span> <span class="nf">_acquireLock</span><span class="p">():</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Acquire the module-level lock for serializing access to shared data.</span>

<span class="sd">    This should be released with _releaseLock().</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">_lock</span><span class="p">:</span>
        <span class="n">_lock</span><span class="o">.</span><span class="n">acquire</span><span class="p">()</span>

<span class="k">def</span> <span class="nf">_releaseLock</span><span class="p">():</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Release the module-level lock acquired by calling _acquireLock().</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">_lock</span><span class="p">:</span>
        <span class="n">_lock</span><span class="o">.</span><span class="n">release</span><span class="p">()</span>

<span class="c1">#---------------------------------------------------------------------------</span>
<span class="c1">#   The logging record</span>
<span class="c1">#---------------------------------------------------------------------------</span>

<div class="viewcode-block" id="LogRecord"><a class="viewcode-back" href="../logging.html#logging.LogRecord">[文档]</a><span class="k">class</span> <span class="nc">LogRecord</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A LogRecord instance represents an event being logged.</span>

<span class="sd">    LogRecord instances are created every time something is logged. They</span>
<span class="sd">    contain all the information pertinent to the event being logged. The</span>
<span class="sd">    main information passed in is in msg and args, which are combined</span>
<span class="sd">    using str(msg) % args to create the message field of the record. The</span>
<span class="sd">    record also includes information such as when the record was created,</span>
<span class="sd">    the source line where the logging call was made, and any exception</span>
<span class="sd">    information to be logged.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">level</span><span class="p">,</span> <span class="n">pathname</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span>
                 <span class="n">msg</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">exc_info</span><span class="p">,</span> <span class="n">func</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">sinfo</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initialize a logging record with interesting information.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">ct</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span>
        <span class="c1">#</span>
        <span class="c1"># The following statement allows passing of a dictionary as a sole</span>
        <span class="c1"># argument, so that you can do something like</span>
        <span class="c1">#  logging.debug(&quot;a %(a)d b %(b)s&quot;, {&#39;a&#39;:1, &#39;b&#39;:2})</span>
        <span class="c1"># Suggested by Stefan Behnel.</span>
        <span class="c1"># Note that without the test for args[0], we get a problem because</span>
        <span class="c1"># during formatting, we test to see if the arg is present using</span>
        <span class="c1"># &#39;if self.args:&#39;. If the event being logged is e.g. &#39;Value is %d&#39;</span>
        <span class="c1"># and if the passed arg fails &#39;if self.args:&#39; then no formatting</span>
        <span class="c1"># is done. For example, logger.warning(&#39;Value is %d&#39;, 0) would log</span>
        <span class="c1"># &#39;Value is %d&#39; instead of &#39;Value is 0&#39;.</span>
        <span class="c1"># For the use case of passing a dictionary, this should not be a</span>
        <span class="c1"># problem.</span>
        <span class="c1"># Issue #21172: a request was made to relax the isinstance check</span>
        <span class="c1"># to hasattr(args[0], &#39;__getitem__&#39;). However, the docs on string</span>
        <span class="c1"># formatting still seem to suggest a mapping object is required.</span>
        <span class="c1"># Thus, while not removing the isinstance check, it does now look</span>
        <span class="c1"># for collections.Mapping rather than, as before, dict.</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">args</span> <span class="ow">and</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">and</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">collections</span><span class="o">.</span><span class="n">Mapping</span><span class="p">)</span>
            <span class="ow">and</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
            <span class="n">args</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">args</span> <span class="o">=</span> <span class="n">args</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">levelname</span> <span class="o">=</span> <span class="n">getLevelName</span><span class="p">(</span><span class="n">level</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">levelno</span> <span class="o">=</span> <span class="n">level</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">pathname</span> <span class="o">=</span> <span class="n">pathname</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">pathname</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">module</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">splitext</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">filename</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
        <span class="k">except</span> <span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">,</span> <span class="ne">AttributeError</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">filename</span> <span class="o">=</span> <span class="n">pathname</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">module</span> <span class="o">=</span> <span class="s2">&quot;Unknown module&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">exc_info</span> <span class="o">=</span> <span class="n">exc_info</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">exc_text</span> <span class="o">=</span> <span class="kc">None</span>      <span class="c1"># used to cache the traceback text</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">stack_info</span> <span class="o">=</span> <span class="n">sinfo</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lineno</span> <span class="o">=</span> <span class="n">lineno</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">funcName</span> <span class="o">=</span> <span class="n">func</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">created</span> <span class="o">=</span> <span class="n">ct</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">msecs</span> <span class="o">=</span> <span class="p">(</span><span class="n">ct</span> <span class="o">-</span> <span class="nb">int</span><span class="p">(</span><span class="n">ct</span><span class="p">))</span> <span class="o">*</span> <span class="mi">1000</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">relativeCreated</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">created</span> <span class="o">-</span> <span class="n">_startTime</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1000</span>
        <span class="k">if</span> <span class="n">logThreads</span> <span class="ow">and</span> <span class="n">threading</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">get_ident</span><span class="p">()</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">threadName</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">current_thread</span><span class="p">()</span><span class="o">.</span><span class="n">name</span>
        <span class="k">else</span><span class="p">:</span> <span class="c1"># pragma: no cover</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">thread</span> <span class="o">=</span> <span class="kc">None</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">threadName</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">logMultiprocessing</span><span class="p">:</span> <span class="c1"># pragma: no cover</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">processName</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">processName</span> <span class="o">=</span> <span class="s1">&#39;MainProcess&#39;</span>
            <span class="n">mp</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;multiprocessing&#39;</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">mp</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="c1"># Errors may occur if multiprocessing has not finished loading</span>
                <span class="c1"># yet - e.g. if a custom import hook causes third-party code</span>
                <span class="c1"># to run when multiprocessing calls import. See issue 8200</span>
                <span class="c1"># for an example</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">processName</span> <span class="o">=</span> <span class="n">mp</span><span class="o">.</span><span class="n">current_process</span><span class="p">()</span><span class="o">.</span><span class="n">name</span>
                <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span> <span class="c1">#pragma: no cover</span>
                    <span class="k">pass</span>
        <span class="k">if</span> <span class="n">logProcesses</span> <span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">os</span><span class="p">,</span> <span class="s1">&#39;getpid&#39;</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">process</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">getpid</span><span class="p">()</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">process</span> <span class="o">=</span> <span class="kc">None</span>

    <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="s1">&#39;&lt;LogRecord: </span><span class="si">%s</span><span class="s1">, </span><span class="si">%s</span><span class="s1">, </span><span class="si">%s</span><span class="s1">, </span><span class="si">%s</span><span class="s1">, &quot;</span><span class="si">%s</span><span class="s1">&quot;&gt;&#39;</span><span class="o">%</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">levelno</span><span class="p">,</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">pathname</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">lineno</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">)</span>

    <span class="fm">__repr__</span> <span class="o">=</span> <span class="fm">__str__</span>

<div class="viewcode-block" id="LogRecord.getMessage"><a class="viewcode-back" href="../logging.html#logging.LogRecord.getMessage">[文档]</a>    <span class="k">def</span> <span class="nf">getMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return the message for this LogRecord.</span>

<span class="sd">        Return the message for this LogRecord after merging any user-supplied</span>
<span class="sd">        arguments with the message.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">msg</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">msg</span><span class="p">)</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">:</span>
            <span class="n">msg</span> <span class="o">=</span> <span class="n">msg</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span>
        <span class="k">return</span> <span class="n">msg</span></div></div>

<span class="c1">#</span>
<span class="c1">#   Determine which class to use when instantiating log records.</span>
<span class="c1">#</span>
<span class="n">_logRecordFactory</span> <span class="o">=</span> <span class="n">LogRecord</span>

<div class="viewcode-block" id="setLogRecordFactory"><a class="viewcode-back" href="../logging.html#logging.setLogRecordFactory">[文档]</a><span class="k">def</span> <span class="nf">setLogRecordFactory</span><span class="p">(</span><span class="n">factory</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Set the factory to be used when instantiating a log record.</span>

<span class="sd">    :param factory: A callable which will be called to instantiate</span>
<span class="sd">    a log record.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">global</span> <span class="n">_logRecordFactory</span>
    <span class="n">_logRecordFactory</span> <span class="o">=</span> <span class="n">factory</span></div>

<div class="viewcode-block" id="getLogRecordFactory"><a class="viewcode-back" href="../logging.html#logging.getLogRecordFactory">[文档]</a><span class="k">def</span> <span class="nf">getLogRecordFactory</span><span class="p">():</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Return the factory to be used when instantiating a log record.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">return</span> <span class="n">_logRecordFactory</span></div>

<div class="viewcode-block" id="makeLogRecord"><a class="viewcode-back" href="../logging.html#logging.makeLogRecord">[文档]</a><span class="k">def</span> <span class="nf">makeLogRecord</span><span class="p">(</span><span class="nb">dict</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Make a LogRecord whose attributes are defined by the specified dictionary,</span>
<span class="sd">    This function is useful for converting a logging event received over</span>
<span class="sd">    a socket connection (which is sent as a dictionary) into a LogRecord</span>
<span class="sd">    instance.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">rv</span> <span class="o">=</span> <span class="n">_logRecordFactory</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="p">(),</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
    <span class="n">rv</span><span class="o">.</span><span class="vm">__dict__</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="nb">dict</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">rv</span></div>

<span class="c1">#---------------------------------------------------------------------------</span>
<span class="c1">#   Formatter classes and functions</span>
<span class="c1">#---------------------------------------------------------------------------</span>

<span class="k">class</span> <span class="nc">PercentStyle</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>

    <span class="n">default_format</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%(message)s</span><span class="s1">&#39;</span>
    <span class="n">asctime_format</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%(asctime)s</span><span class="s1">&#39;</span>
    <span class="n">asctime_search</span> <span class="o">=</span> <span class="s1">&#39;%(asctime)&#39;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fmt</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_fmt</span> <span class="o">=</span> <span class="n">fmt</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_format</span>

    <span class="k">def</span> <span class="nf">usesTime</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fmt</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asctime_search</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span>

    <span class="k">def</span> <span class="nf">format</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fmt</span> <span class="o">%</span> <span class="n">record</span><span class="o">.</span><span class="vm">__dict__</span>

<span class="k">class</span> <span class="nc">StrFormatStyle</span><span class="p">(</span><span class="n">PercentStyle</span><span class="p">):</span>
    <span class="n">default_format</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">{message}</span><span class="s1">&#39;</span>
    <span class="n">asctime_format</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">{asctime}</span><span class="s1">&#39;</span>
    <span class="n">asctime_search</span> <span class="o">=</span> <span class="s1">&#39;{asctime&#39;</span>

    <span class="k">def</span> <span class="nf">format</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fmt</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="o">**</span><span class="n">record</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">)</span>


<span class="k">class</span> <span class="nc">StringTemplateStyle</span><span class="p">(</span><span class="n">PercentStyle</span><span class="p">):</span>
    <span class="n">default_format</span> <span class="o">=</span> <span class="s1">&#39;$</span><span class="si">{message}</span><span class="s1">&#39;</span>
    <span class="n">asctime_format</span> <span class="o">=</span> <span class="s1">&#39;$</span><span class="si">{asctime}</span><span class="s1">&#39;</span>
    <span class="n">asctime_search</span> <span class="o">=</span> <span class="s1">&#39;$</span><span class="si">{asctime}</span><span class="s1">&#39;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fmt</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_fmt</span> <span class="o">=</span> <span class="n">fmt</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_format</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_tpl</span> <span class="o">=</span> <span class="n">Template</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_fmt</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">usesTime</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">fmt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fmt</span>
        <span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s1">&#39;$asctime&#39;</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">fmt</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asctime_format</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">0</span>

    <span class="k">def</span> <span class="nf">format</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_tpl</span><span class="o">.</span><span class="n">substitute</span><span class="p">(</span><span class="o">**</span><span class="n">record</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">)</span>

<span class="n">BASIC_FORMAT</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%(levelname)s</span><span class="s2">:</span><span class="si">%(name)s</span><span class="s2">:</span><span class="si">%(message)s</span><span class="s2">&quot;</span>

<span class="n">_STYLES</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s1">&#39;%&#39;</span><span class="p">:</span> <span class="p">(</span><span class="n">PercentStyle</span><span class="p">,</span> <span class="n">BASIC_FORMAT</span><span class="p">),</span>
    <span class="s1">&#39;{&#39;</span><span class="p">:</span> <span class="p">(</span><span class="n">StrFormatStyle</span><span class="p">,</span> <span class="s1">&#39;</span><span class="si">{levelname}</span><span class="s1">:</span><span class="si">{name}</span><span class="s1">:</span><span class="si">{message}</span><span class="s1">&#39;</span><span class="p">),</span>
    <span class="s1">&#39;$&#39;</span><span class="p">:</span> <span class="p">(</span><span class="n">StringTemplateStyle</span><span class="p">,</span> <span class="s1">&#39;$</span><span class="si">{levelname}</span><span class="s1">:$</span><span class="si">{name}</span><span class="s1">:$</span><span class="si">{message}</span><span class="s1">&#39;</span><span class="p">),</span>
<span class="p">}</span>

<div class="viewcode-block" id="Formatter"><a class="viewcode-back" href="../logging.html#logging.Formatter">[文档]</a><span class="k">class</span> <span class="nc">Formatter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Formatter instances are used to convert a LogRecord to text.</span>

<span class="sd">    Formatters need to know how a LogRecord is constructed. They are</span>
<span class="sd">    responsible for converting a LogRecord to (usually) a string which can</span>
<span class="sd">    be interpreted by either a human or an external system. The base Formatter</span>
<span class="sd">    allows a formatting string to be specified. If none is supplied, the</span>
<span class="sd">    default value of &quot;%s(message)&quot; is used.</span>

<span class="sd">    The Formatter can be initialized with a format string which makes use of</span>
<span class="sd">    knowledge of the LogRecord attributes - e.g. the default value mentioned</span>
<span class="sd">    above makes use of the fact that the user&#39;s message and arguments are pre-</span>
<span class="sd">    formatted into a LogRecord&#39;s message attribute. Currently, the useful</span>
<span class="sd">    attributes in a LogRecord are described by:</span>

<span class="sd">    %(name)s            Name of the logger (logging channel)</span>
<span class="sd">    %(levelno)s         Numeric logging level for the message (DEBUG, INFO,</span>
<span class="sd">                        WARNING, ERROR, CRITICAL)</span>
<span class="sd">    %(levelname)s       Text logging level for the message (&quot;DEBUG&quot;, &quot;INFO&quot;,</span>
<span class="sd">                        &quot;WARNING&quot;, &quot;ERROR&quot;, &quot;CRITICAL&quot;)</span>
<span class="sd">    %(pathname)s        Full pathname of the source file where the logging</span>
<span class="sd">                        call was issued (if available)</span>
<span class="sd">    %(filename)s        Filename portion of pathname</span>
<span class="sd">    %(module)s          Module (name portion of filename)</span>
<span class="sd">    %(lineno)d          Source line number where the logging call was issued</span>
<span class="sd">                        (if available)</span>
<span class="sd">    %(funcName)s        Function name</span>
<span class="sd">    %(created)f         Time when the LogRecord was created (time.time()</span>
<span class="sd">                        return value)</span>
<span class="sd">    %(asctime)s         Textual time when the LogRecord was created</span>
<span class="sd">    %(msecs)d           Millisecond portion of the creation time</span>
<span class="sd">    %(relativeCreated)d Time in milliseconds when the LogRecord was created,</span>
<span class="sd">                        relative to the time the logging module was loaded</span>
<span class="sd">                        (typically at application startup time)</span>
<span class="sd">    %(thread)d          Thread ID (if available)</span>
<span class="sd">    %(threadName)s      Thread name (if available)</span>
<span class="sd">    %(process)d         Process ID (if available)</span>
<span class="sd">    %(message)s         The result of record.getMessage(), computed just as</span>
<span class="sd">                        the record is emitted</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="n">converter</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">localtime</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fmt</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">datefmt</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">style</span><span class="o">=</span><span class="s1">&#39;%&#39;</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initialize the formatter with specified format strings.</span>

<span class="sd">        Initialize the formatter either with the specified format string, or a</span>
<span class="sd">        default as described above. Allow for specialized date formatting with</span>
<span class="sd">        the optional datefmt argument (if omitted, you get the ISO8601 format).</span>

<span class="sd">        Use a style parameter of &#39;%&#39;, &#39;{&#39; or &#39;$&#39; to specify that you want to</span>
<span class="sd">        use one of %-formatting, :meth:`str.format` (``{}``) formatting or</span>
<span class="sd">        :class:`string.Template` formatting in your format string.</span>

<span class="sd">        .. versionchanged:: 3.2</span>
<span class="sd">           Added the ``style`` parameter.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">style</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">_STYLES</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;Style must be one of: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="s1">&#39;,&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
                             <span class="n">_STYLES</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_style</span> <span class="o">=</span> <span class="n">_STYLES</span><span class="p">[</span><span class="n">style</span><span class="p">][</span><span class="mi">0</span><span class="p">](</span><span class="n">fmt</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_fmt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_style</span><span class="o">.</span><span class="n">_fmt</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">datefmt</span> <span class="o">=</span> <span class="n">datefmt</span>

    <span class="n">default_time_format</span> <span class="o">=</span> <span class="s1">&#39;%Y-%m-</span><span class="si">%d</span><span class="s1"> %H:%M:%S&#39;</span>
    <span class="n">default_msec_format</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">%s</span><span class="s1">,</span><span class="si">%03d</span><span class="s1">&#39;</span>

<div class="viewcode-block" id="Formatter.formatTime"><a class="viewcode-back" href="../logging.html#logging.Formatter.formatTime">[文档]</a>    <span class="k">def</span> <span class="nf">formatTime</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">,</span> <span class="n">datefmt</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return the creation time of the specified LogRecord as formatted text.</span>

<span class="sd">        This method should be called from format() by a formatter which</span>
<span class="sd">        wants to make use of a formatted time. This method can be overridden</span>
<span class="sd">        in formatters to provide for any specific requirement, but the</span>
<span class="sd">        basic behaviour is as follows: if datefmt (a string) is specified,</span>
<span class="sd">        it is used with time.strftime() to format the creation time of the</span>
<span class="sd">        record. Otherwise, the ISO8601 format is used. The resulting</span>
<span class="sd">        string is returned. This function uses a user-configurable function</span>
<span class="sd">        to convert the creation time to a tuple. By default, time.localtime()</span>
<span class="sd">        is used; to change this for a particular formatter instance, set the</span>
<span class="sd">        &#39;converter&#39; attribute to a function with the same signature as</span>
<span class="sd">        time.localtime() or time.gmtime(). To change it for all formatters,</span>
<span class="sd">        for example if you want all logging times to be shown in GMT,</span>
<span class="sd">        set the &#39;converter&#39; attribute in the Formatter class.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">ct</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">converter</span><span class="p">(</span><span class="n">record</span><span class="o">.</span><span class="n">created</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">datefmt</span><span class="p">:</span>
            <span class="n">s</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="n">datefmt</span><span class="p">,</span> <span class="n">ct</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">t</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">default_time_format</span><span class="p">,</span> <span class="n">ct</span><span class="p">)</span>
            <span class="n">s</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">default_msec_format</span> <span class="o">%</span> <span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">record</span><span class="o">.</span><span class="n">msecs</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">s</span></div>

<div class="viewcode-block" id="Formatter.formatException"><a class="viewcode-back" href="../logging.html#logging.Formatter.formatException">[文档]</a>    <span class="k">def</span> <span class="nf">formatException</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ei</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Format and return the specified exception information as a string.</span>

<span class="sd">        This default implementation just uses</span>
<span class="sd">        traceback.print_exception()</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">sio</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">StringIO</span><span class="p">()</span>
        <span class="n">tb</span> <span class="o">=</span> <span class="n">ei</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
        <span class="c1"># See issues #9427, #1553375. Commented out for now.</span>
        <span class="c1">#if getattr(self, &#39;fullstack&#39;, False):</span>
        <span class="c1">#    traceback.print_stack(tb.tb_frame.f_back, file=sio)</span>
        <span class="n">traceback</span><span class="o">.</span><span class="n">print_exception</span><span class="p">(</span><span class="n">ei</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">ei</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">tb</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">sio</span><span class="p">)</span>
        <span class="n">s</span> <span class="o">=</span> <span class="n">sio</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
        <span class="n">sio</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">s</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">:]</span> <span class="o">==</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">:</span>
            <span class="n">s</span> <span class="o">=</span> <span class="n">s</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
        <span class="k">return</span> <span class="n">s</span></div>

<div class="viewcode-block" id="Formatter.usesTime"><a class="viewcode-back" href="../logging.html#logging.Formatter.usesTime">[文档]</a>    <span class="k">def</span> <span class="nf">usesTime</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Check if the format uses the creation time of the record.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_style</span><span class="o">.</span><span class="n">usesTime</span><span class="p">()</span></div>

<div class="viewcode-block" id="Formatter.formatMessage"><a class="viewcode-back" href="../logging.html#logging.Formatter.formatMessage">[文档]</a>    <span class="k">def</span> <span class="nf">formatMessage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_style</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">record</span><span class="p">)</span></div>

<div class="viewcode-block" id="Formatter.formatStack"><a class="viewcode-back" href="../logging.html#logging.Formatter.formatStack">[文档]</a>    <span class="k">def</span> <span class="nf">formatStack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stack_info</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        This method is provided as an extension point for specialized</span>
<span class="sd">        formatting of stack information.</span>

<span class="sd">        The input data is a string as returned from a call to</span>
<span class="sd">        :func:`traceback.print_stack`, but with the last trailing newline</span>
<span class="sd">        removed.</span>

<span class="sd">        The base implementation just returns the value passed in.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">stack_info</span></div>

<div class="viewcode-block" id="Formatter.format"><a class="viewcode-back" href="../logging.html#logging.Formatter.format">[文档]</a>    <span class="k">def</span> <span class="nf">format</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Format the specified record as text.</span>

<span class="sd">        The record&#39;s attribute dictionary is used as the operand to a</span>
<span class="sd">        string formatting operation which yields the returned string.</span>
<span class="sd">        Before formatting the dictionary, a couple of preparatory steps</span>
<span class="sd">        are carried out. The message attribute of the record is computed</span>
<span class="sd">        using LogRecord.getMessage(). If the formatting string uses the</span>
<span class="sd">        time (as determined by a call to usesTime(), formatTime() is</span>
<span class="sd">        called to format the event time. If there is exception information,</span>
<span class="sd">        it is formatted using formatException() and appended to the message.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">record</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">record</span><span class="o">.</span><span class="n">getMessage</span><span class="p">()</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">usesTime</span><span class="p">():</span>
            <span class="n">record</span><span class="o">.</span><span class="n">asctime</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">formatTime</span><span class="p">(</span><span class="n">record</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">datefmt</span><span class="p">)</span>
        <span class="n">s</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">formatMessage</span><span class="p">(</span><span class="n">record</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">record</span><span class="o">.</span><span class="n">exc_info</span><span class="p">:</span>
            <span class="c1"># Cache the traceback text to avoid converting it multiple times</span>
            <span class="c1"># (it&#39;s constant anyway)</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">record</span><span class="o">.</span><span class="n">exc_text</span><span class="p">:</span>
                <span class="n">record</span><span class="o">.</span><span class="n">exc_text</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">formatException</span><span class="p">(</span><span class="n">record</span><span class="o">.</span><span class="n">exc_info</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">record</span><span class="o">.</span><span class="n">exc_text</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">s</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">:]</span> <span class="o">!=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">:</span>
                <span class="n">s</span> <span class="o">=</span> <span class="n">s</span> <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span>
            <span class="n">s</span> <span class="o">=</span> <span class="n">s</span> <span class="o">+</span> <span class="n">record</span><span class="o">.</span><span class="n">exc_text</span>
        <span class="k">if</span> <span class="n">record</span><span class="o">.</span><span class="n">stack_info</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">s</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">:]</span> <span class="o">!=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">:</span>
                <span class="n">s</span> <span class="o">=</span> <span class="n">s</span> <span class="o">+</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span>
            <span class="n">s</span> <span class="o">=</span> <span class="n">s</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">formatStack</span><span class="p">(</span><span class="n">record</span><span class="o">.</span><span class="n">stack_info</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">s</span></div></div>

<span class="c1">#</span>
<span class="c1">#   The default formatter to use when no other is specified</span>
<span class="c1">#</span>
<span class="n">_defaultFormatter</span> <span class="o">=</span> <span class="n">Formatter</span><span class="p">()</span>

<div class="viewcode-block" id="BufferingFormatter"><a class="viewcode-back" href="../logging.html#logging.BufferingFormatter">[文档]</a><span class="k">class</span> <span class="nc">BufferingFormatter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A formatter suitable for formatting a number of records.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">linefmt</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Optionally specify a formatter which will be used to format each</span>
<span class="sd">        individual record.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">linefmt</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">linefmt</span> <span class="o">=</span> <span class="n">linefmt</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">linefmt</span> <span class="o">=</span> <span class="n">_defaultFormatter</span>

<div class="viewcode-block" id="BufferingFormatter.formatHeader"><a class="viewcode-back" href="../logging.html#logging.BufferingFormatter.formatHeader">[文档]</a>    <span class="k">def</span> <span class="nf">formatHeader</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">records</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return the header string for the specified records.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="s2">&quot;&quot;</span></div>

<div class="viewcode-block" id="BufferingFormatter.formatFooter"><a class="viewcode-back" href="../logging.html#logging.BufferingFormatter.formatFooter">[文档]</a>    <span class="k">def</span> <span class="nf">formatFooter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">records</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return the footer string for the specified records.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="s2">&quot;&quot;</span></div>

<div class="viewcode-block" id="BufferingFormatter.format"><a class="viewcode-back" href="../logging.html#logging.BufferingFormatter.format">[文档]</a>    <span class="k">def</span> <span class="nf">format</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">records</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Format the specified records and return the result as a string.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">rv</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">records</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
            <span class="n">rv</span> <span class="o">=</span> <span class="n">rv</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">formatHeader</span><span class="p">(</span><span class="n">records</span><span class="p">)</span>
            <span class="k">for</span> <span class="n">record</span> <span class="ow">in</span> <span class="n">records</span><span class="p">:</span>
                <span class="n">rv</span> <span class="o">=</span> <span class="n">rv</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">linefmt</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">record</span><span class="p">)</span>
            <span class="n">rv</span> <span class="o">=</span> <span class="n">rv</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">formatFooter</span><span class="p">(</span><span class="n">records</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">rv</span></div></div>

<span class="c1">#---------------------------------------------------------------------------</span>
<span class="c1">#   Filter classes and functions</span>
<span class="c1">#---------------------------------------------------------------------------</span>

<div class="viewcode-block" id="Filter"><a class="viewcode-back" href="../logging.html#logging.Filter">[文档]</a><span class="k">class</span> <span class="nc">Filter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Filter instances are used to perform arbitrary filtering of LogRecords.</span>

<span class="sd">    Loggers and Handlers can optionally use Filter instances to filter</span>
<span class="sd">    records as desired. The base filter class only allows events which are</span>
<span class="sd">    below a certain point in the logger hierarchy. For example, a filter</span>
<span class="sd">    initialized with &quot;A.B&quot; will allow events logged by loggers &quot;A.B&quot;,</span>
<span class="sd">    &quot;A.B.C&quot;, &quot;A.B.C.D&quot;, &quot;A.B.D&quot; etc. but not &quot;A.BB&quot;, &quot;B.A.B&quot; etc. If</span>
<span class="sd">    initialized with the empty string, all events are passed.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">&#39;&#39;</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initialize a filter.</span>

<span class="sd">        Initialize with the name of the logger which, together with its</span>
<span class="sd">        children, will have its events allowed through the filter. If no</span>
<span class="sd">        name is specified, allow every event.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">nlen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>

<div class="viewcode-block" id="Filter.filter"><a class="viewcode-back" href="../logging.html#logging.Filter.filter">[文档]</a>    <span class="k">def</span> <span class="nf">filter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Determine if the specified record is to be logged.</span>

<span class="sd">        Is the specified record to be logged? Returns 0 for no, nonzero for</span>
<span class="sd">        yes. If deemed appropriate, the record may be modified in-place.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">nlen</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span> <span class="kc">True</span>
        <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="n">record</span><span class="o">.</span><span class="n">name</span><span class="p">:</span>
            <span class="k">return</span> <span class="kc">True</span>
        <span class="k">elif</span> <span class="n">record</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">nlen</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
            <span class="k">return</span> <span class="kc">False</span>
        <span class="k">return</span> <span class="p">(</span><span class="n">record</span><span class="o">.</span><span class="n">name</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">nlen</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;.&quot;</span><span class="p">)</span></div></div>

<span class="k">class</span> <span class="nc">Filterer</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A base class for loggers and handlers which allows them to share</span>
<span class="sd">    common code.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initialize the list of filters to be an empty list.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">filters</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">def</span> <span class="nf">addFilter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">filter</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Add the specified filter to this handler.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="nb">filter</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">filters</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">filters</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">filter</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">removeFilter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">filter</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Remove the specified filter from this handler.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="nb">filter</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">filters</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">filters</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="nb">filter</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">filter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Determine if a record is loggable by consulting all the filters.</span>

<span class="sd">        The default is to allow the record to be logged; any filter can veto</span>
<span class="sd">        this and the record is then dropped. Returns a zero value if a record</span>
<span class="sd">        is to be dropped, else non-zero.</span>

<span class="sd">        .. versionchanged:: 3.2</span>

<span class="sd">           Allow filters to be just callables.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">rv</span> <span class="o">=</span> <span class="kc">True</span>
        <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">filters</span><span class="p">:</span>
            <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s1">&#39;filter&#39;</span><span class="p">):</span>
                <span class="n">result</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">record</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">result</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">record</span><span class="p">)</span> <span class="c1"># assume callable - will raise if not</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">result</span><span class="p">:</span>
                <span class="n">rv</span> <span class="o">=</span> <span class="kc">False</span>
                <span class="k">break</span>
        <span class="k">return</span> <span class="n">rv</span>

<span class="c1">#---------------------------------------------------------------------------</span>
<span class="c1">#   Handler classes and functions</span>
<span class="c1">#---------------------------------------------------------------------------</span>

<span class="n">_handlers</span> <span class="o">=</span> <span class="n">weakref</span><span class="o">.</span><span class="n">WeakValueDictionary</span><span class="p">()</span>  <span class="c1">#map of handler names to handlers</span>
<span class="n">_handlerList</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># added to allow handlers to be removed in reverse of order initialized</span>

<span class="k">def</span> <span class="nf">_removeHandlerRef</span><span class="p">(</span><span class="n">wr</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Remove a handler reference from the internal cleanup list.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="c1"># This function can be called during module teardown, when globals are</span>
    <span class="c1"># set to None. It can also be called from another thread. So we need to</span>
    <span class="c1"># pre-emptively grab the necessary globals and check if they&#39;re None,</span>
    <span class="c1"># to prevent race conditions and failures during interpreter shutdown.</span>
    <span class="n">acquire</span><span class="p">,</span> <span class="n">release</span><span class="p">,</span> <span class="n">handlers</span> <span class="o">=</span> <span class="n">_acquireLock</span><span class="p">,</span> <span class="n">_releaseLock</span><span class="p">,</span> <span class="n">_handlerList</span>
    <span class="k">if</span> <span class="n">acquire</span> <span class="ow">and</span> <span class="n">release</span> <span class="ow">and</span> <span class="n">handlers</span><span class="p">:</span>
        <span class="n">acquire</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">wr</span> <span class="ow">in</span> <span class="n">handlers</span><span class="p">:</span>
                <span class="n">handlers</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">wr</span><span class="p">)</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="n">release</span><span class="p">()</span>

<span class="k">def</span> <span class="nf">_addHandlerRef</span><span class="p">(</span><span class="n">handler</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Add a handler to the internal cleanup list using a weak reference.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">_acquireLock</span><span class="p">()</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="n">_handlerList</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">weakref</span><span class="o">.</span><span class="n">ref</span><span class="p">(</span><span class="n">handler</span><span class="p">,</span> <span class="n">_removeHandlerRef</span><span class="p">))</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="n">_releaseLock</span><span class="p">()</span>

<div class="viewcode-block" id="Handler"><a class="viewcode-back" href="../logging.html#logging.Handler">[文档]</a><span class="k">class</span> <span class="nc">Handler</span><span class="p">(</span><span class="n">Filterer</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Handler instances dispatch logging events to specific destinations.</span>

<span class="sd">    The base handler class. Acts as a placeholder which defines the Handler</span>
<span class="sd">    interface. Handlers can optionally use Formatter instances to format</span>
<span class="sd">    records as desired. By default, no formatter is specified; in this case,</span>
<span class="sd">    the &#39;raw&#39; message as determined by record.message is logged.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="n">NOTSET</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initializes the instance - basically setting the formatter to None</span>
<span class="sd">        and the filter list to empty.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">Filterer</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">level</span> <span class="o">=</span> <span class="n">_checkLevel</span><span class="p">(</span><span class="n">level</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">formatter</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="c1"># Add the handler to the global _handlerList (for cleanup on shutdown)</span>
        <span class="n">_addHandlerRef</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">createLock</span><span class="p">()</span>

<div class="viewcode-block" id="Handler.get_name"><a class="viewcode-back" href="../logging.html#logging.Handler.get_name">[文档]</a>    <span class="k">def</span> <span class="nf">get_name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span></div>

<div class="viewcode-block" id="Handler.set_name"><a class="viewcode-back" href="../logging.html#logging.Handler.set_name">[文档]</a>    <span class="k">def</span> <span class="nf">set_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
        <span class="n">_acquireLock</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="ow">in</span> <span class="n">_handlers</span><span class="p">:</span>
                <span class="k">del</span> <span class="n">_handlers</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">]</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="n">name</span>
            <span class="k">if</span> <span class="n">name</span><span class="p">:</span>
                <span class="n">_handlers</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="n">_releaseLock</span><span class="p">()</span></div>

    <span class="n">name</span> <span class="o">=</span> <span class="nb">property</span><span class="p">(</span><span class="n">get_name</span><span class="p">,</span> <span class="n">set_name</span><span class="p">)</span>

<div class="viewcode-block" id="Handler.createLock"><a class="viewcode-back" href="../logging.html#logging.Handler.createLock">[文档]</a>    <span class="k">def</span> <span class="nf">createLock</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Acquire a thread lock for serializing access to the underlying I/O.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">threading</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">lock</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">RLock</span><span class="p">()</span>
        <span class="k">else</span><span class="p">:</span> <span class="c1">#pragma: no cover</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">lock</span> <span class="o">=</span> <span class="kc">None</span></div>

<div class="viewcode-block" id="Handler.acquire"><a class="viewcode-back" href="../logging.html#logging.Handler.acquire">[文档]</a>    <span class="k">def</span> <span class="nf">acquire</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Acquire the I/O thread lock.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">lock</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">lock</span><span class="o">.</span><span class="n">acquire</span><span class="p">()</span></div>

<div class="viewcode-block" id="Handler.release"><a class="viewcode-back" href="../logging.html#logging.Handler.release">[文档]</a>    <span class="k">def</span> <span class="nf">release</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Release the I/O thread lock.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">lock</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">lock</span><span class="o">.</span><span class="n">release</span><span class="p">()</span></div>

<div class="viewcode-block" id="Handler.setLevel"><a class="viewcode-back" href="../logging.html#logging.Handler.setLevel">[文档]</a>    <span class="k">def</span> <span class="nf">setLevel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Set the logging level of this handler.  level must be an int or a str.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">level</span> <span class="o">=</span> <span class="n">_checkLevel</span><span class="p">(</span><span class="n">level</span><span class="p">)</span></div>

<div class="viewcode-block" id="Handler.format"><a class="viewcode-back" href="../logging.html#logging.Handler.format">[文档]</a>    <span class="k">def</span> <span class="nf">format</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Format the specified record.</span>

<span class="sd">        If a formatter is set, use it. Otherwise, use the default formatter</span>
<span class="sd">        for the module.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">formatter</span><span class="p">:</span>
            <span class="n">fmt</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">formatter</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">fmt</span> <span class="o">=</span> <span class="n">_defaultFormatter</span>
        <span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">record</span><span class="p">)</span></div>

<div class="viewcode-block" id="Handler.emit"><a class="viewcode-back" href="../logging.html#logging.Handler.emit">[文档]</a>    <span class="k">def</span> <span class="nf">emit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Do whatever it takes to actually log the specified logging record.</span>

<span class="sd">        This version is intended to be implemented by subclasses and so</span>
<span class="sd">        raises a NotImplementedError.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="s1">&#39;emit must be implemented &#39;</span>
                                  <span class="s1">&#39;by Handler subclasses&#39;</span><span class="p">)</span></div>

<div class="viewcode-block" id="Handler.handle"><a class="viewcode-back" href="../logging.html#logging.Handler.handle">[文档]</a>    <span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Conditionally emit the specified logging record.</span>

<span class="sd">        Emission depends on filters which may have been added to the handler.</span>
<span class="sd">        Wrap the actual emission of the record with acquisition/release of</span>
<span class="sd">        the I/O thread lock. Returns whether the filter passed the record for</span>
<span class="sd">        emission.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">rv</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">record</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">rv</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">acquire</span><span class="p">()</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">emit</span><span class="p">(</span><span class="n">record</span><span class="p">)</span>
            <span class="k">finally</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">release</span><span class="p">()</span>
        <span class="k">return</span> <span class="n">rv</span></div>

<div class="viewcode-block" id="Handler.setFormatter"><a class="viewcode-back" href="../logging.html#logging.Handler.setFormatter">[文档]</a>    <span class="k">def</span> <span class="nf">setFormatter</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fmt</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Set the formatter for this handler.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">formatter</span> <span class="o">=</span> <span class="n">fmt</span></div>

<div class="viewcode-block" id="Handler.flush"><a class="viewcode-back" href="../logging.html#logging.Handler.flush">[文档]</a>    <span class="k">def</span> <span class="nf">flush</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Ensure all logging output has been flushed.</span>

<span class="sd">        This version does nothing and is intended to be implemented by</span>
<span class="sd">        subclasses.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">pass</span></div>

<div class="viewcode-block" id="Handler.close"><a class="viewcode-back" href="../logging.html#logging.Handler.close">[文档]</a>    <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Tidy up any resources used by the handler.</span>

<span class="sd">        This version removes the handler from an internal map of handlers,</span>
<span class="sd">        _handlers, which is used for handler lookup by name. Subclasses</span>
<span class="sd">        should ensure that this gets called from overridden close()</span>
<span class="sd">        methods.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1">#get the module data lock, as we&#39;re updating a shared structure.</span>
        <span class="n">_acquireLock</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>    <span class="c1">#unlikely to raise an exception, but you never know...</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="ow">in</span> <span class="n">_handlers</span><span class="p">:</span>
                <span class="k">del</span> <span class="n">_handlers</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_name</span><span class="p">]</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="n">_releaseLock</span><span class="p">()</span></div>

<div class="viewcode-block" id="Handler.handleError"><a class="viewcode-back" href="../logging.html#logging.Handler.handleError">[文档]</a>    <span class="k">def</span> <span class="nf">handleError</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Handle errors which occur during an emit() call.</span>

<span class="sd">        This method should be called from handlers when an exception is</span>
<span class="sd">        encountered during an emit() call. If raiseExceptions is false,</span>
<span class="sd">        exceptions get silently ignored. This is what is mostly wanted</span>
<span class="sd">        for a logging system - most users will not care about errors in</span>
<span class="sd">        the logging system, they are more interested in application errors.</span>
<span class="sd">        You could, however, replace this with a custom handler if you wish.</span>
<span class="sd">        The record which was being processed is passed in to this method.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">raiseExceptions</span> <span class="ow">and</span> <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">:</span>  <span class="c1"># see issue 13807</span>
            <span class="n">t</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">tb</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;--- Logging error ---</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
                <span class="n">traceback</span><span class="o">.</span><span class="n">print_exception</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">tb</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
                <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Call stack:</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
                <span class="c1"># Walk the stack frame up until we&#39;re out of logging,</span>
                <span class="c1"># so as to print the calling context.</span>
                <span class="n">frame</span> <span class="o">=</span> <span class="n">tb</span><span class="o">.</span><span class="n">tb_frame</span>
                <span class="k">while</span> <span class="p">(</span><span class="n">frame</span> <span class="ow">and</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">frame</span><span class="o">.</span><span class="n">f_code</span><span class="o">.</span><span class="n">co_filename</span><span class="p">)</span> <span class="o">==</span>
                       <span class="n">__path__</span><span class="p">[</span><span class="mi">0</span><span class="p">]):</span>
                    <span class="n">frame</span> <span class="o">=</span> <span class="n">frame</span><span class="o">.</span><span class="n">f_back</span>
                <span class="k">if</span> <span class="n">frame</span><span class="p">:</span>
                    <span class="n">traceback</span><span class="o">.</span><span class="n">print_stack</span><span class="p">(</span><span class="n">frame</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="c1"># couldn&#39;t find the right stack frame, for some reason</span>
                    <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Logged from file </span><span class="si">%s</span><span class="s1">, line </span><span class="si">%s</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span>
                                     <span class="n">record</span><span class="o">.</span><span class="n">filename</span><span class="p">,</span> <span class="n">record</span><span class="o">.</span><span class="n">lineno</span><span class="p">))</span>
                <span class="c1"># Issue 18671: output logging message and arguments</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Message: </span><span class="si">%r</span><span class="se">\n</span><span class="s1">&#39;</span>
                                     <span class="s1">&#39;Arguments: </span><span class="si">%s</span><span class="se">\n</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">record</span><span class="o">.</span><span class="n">msg</span><span class="p">,</span>
                                                          <span class="n">record</span><span class="o">.</span><span class="n">args</span><span class="p">))</span>
                <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
                    <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Unable to print the message and arguments&#39;</span>
                                     <span class="s1">&#39; - possible formatting error.</span><span class="se">\n</span><span class="s1">Use the&#39;</span>
                                     <span class="s1">&#39; traceback above to help find the error.</span><span class="se">\n</span><span class="s1">&#39;</span>
                                    <span class="p">)</span>
            <span class="k">except</span> <span class="ne">OSError</span><span class="p">:</span> <span class="c1">#pragma: no cover</span>
                <span class="k">pass</span>    <span class="c1"># see issue 5971</span>
            <span class="k">finally</span><span class="p">:</span>
                <span class="k">del</span> <span class="n">t</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">tb</span></div></div>

<div class="viewcode-block" id="StreamHandler"><a class="viewcode-back" href="../logging.html#logging.StreamHandler">[文档]</a><span class="k">class</span> <span class="nc">StreamHandler</span><span class="p">(</span><span class="n">Handler</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A handler class which writes logging records, appropriately formatted,</span>
<span class="sd">    to a stream. Note that this class does not close the stream, as</span>
<span class="sd">    sys.stdout or sys.stderr may be used.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="n">terminator</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stream</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initialize the handler.</span>

<span class="sd">        If stream is not specified, sys.stderr is used.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">Handler</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">stream</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">stream</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">stream</span> <span class="o">=</span> <span class="n">stream</span>

<div class="viewcode-block" id="StreamHandler.flush"><a class="viewcode-back" href="../logging.html#logging.StreamHandler.flush">[文档]</a>    <span class="k">def</span> <span class="nf">flush</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Flushes the stream.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">acquire</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span> <span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">stream</span><span class="p">,</span> <span class="s2">&quot;flush&quot;</span><span class="p">):</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">stream</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">release</span><span class="p">()</span></div>

<div class="viewcode-block" id="StreamHandler.emit"><a class="viewcode-back" href="../logging.html#logging.StreamHandler.emit">[文档]</a>    <span class="k">def</span> <span class="nf">emit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Emit a record.</span>

<span class="sd">        If a formatter is specified, it is used to format the record.</span>
<span class="sd">        The record is then written to the stream with a trailing newline.  If</span>
<span class="sd">        exception information is present, it is formatted using</span>
<span class="sd">        traceback.print_exception and appended to the stream.  If the stream</span>
<span class="sd">        has an &#39;encoding&#39; attribute, it is used to determine how to do the</span>
<span class="sd">        output to the stream.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">msg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">record</span><span class="p">)</span>
            <span class="n">stream</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span>
            <span class="n">stream</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
            <span class="n">stream</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">terminator</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
        <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">handleError</span><span class="p">(</span><span class="n">record</span><span class="p">)</span></div></div>

<div class="viewcode-block" id="FileHandler"><a class="viewcode-back" href="../logging.html#logging.FileHandler">[文档]</a><span class="k">class</span> <span class="nc">FileHandler</span><span class="p">(</span><span class="n">StreamHandler</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A handler class which writes formatted logging records to disk files.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">&#39;a&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">delay</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Open the specified file and use it as the stream for logging.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1">#keep the absolute path, otherwise derived classes which use this</span>
        <span class="c1">#may come a cropper when the current directory changes</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">baseFilename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">mode</span> <span class="o">=</span> <span class="n">mode</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">encoding</span> <span class="o">=</span> <span class="n">encoding</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">delay</span> <span class="o">=</span> <span class="n">delay</span>
        <span class="k">if</span> <span class="n">delay</span><span class="p">:</span>
            <span class="c1">#We don&#39;t open the stream, but we still need to call the</span>
            <span class="c1">#Handler constructor to set level, formatter, lock etc.</span>
            <span class="n">Handler</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">stream</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">StreamHandler</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_open</span><span class="p">())</span>

<div class="viewcode-block" id="FileHandler.close"><a class="viewcode-back" href="../logging.html#logging.FileHandler.close">[文档]</a>    <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Closes the stream.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">acquire</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span><span class="p">:</span>
                    <span class="k">try</span><span class="p">:</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
                    <span class="k">finally</span><span class="p">:</span>
                        <span class="n">stream</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">stream</span> <span class="o">=</span> <span class="kc">None</span>
                        <span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">stream</span><span class="p">,</span> <span class="s2">&quot;close&quot;</span><span class="p">):</span>
                            <span class="n">stream</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
            <span class="k">finally</span><span class="p">:</span>
                <span class="c1"># Issue #19523: call unconditionally to</span>
                <span class="c1"># prevent a handler leak when delay is set</span>
                <span class="n">StreamHandler</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">release</span><span class="p">()</span></div>

    <span class="k">def</span> <span class="nf">_open</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Open the current base file with the (original) mode and encoding.</span>
<span class="sd">        Return the resulting stream.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="nb">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">baseFilename</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">mode</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">encoding</span><span class="p">)</span>

<div class="viewcode-block" id="FileHandler.emit"><a class="viewcode-back" href="../logging.html#logging.FileHandler.emit">[文档]</a>    <span class="k">def</span> <span class="nf">emit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Emit a record.</span>

<span class="sd">        If the stream was not opened because &#39;delay&#39; was specified in the</span>
<span class="sd">        constructor, open it before calling the superclass&#39;s emit.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">stream</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">stream</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_open</span><span class="p">()</span>
        <span class="n">StreamHandler</span><span class="o">.</span><span class="n">emit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">)</span></div></div>

<span class="k">class</span> <span class="nc">_StderrHandler</span><span class="p">(</span><span class="n">StreamHandler</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    This class is like a StreamHandler using sys.stderr, but always uses</span>
<span class="sd">    whatever sys.stderr is currently set to rather than the value of</span>
<span class="sd">    sys.stderr at handler construction time.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="n">NOTSET</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initialize the handler.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">Handler</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">)</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">stream</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span>


<span class="n">_defaultLastResort</span> <span class="o">=</span> <span class="n">_StderrHandler</span><span class="p">(</span><span class="n">WARNING</span><span class="p">)</span>
<span class="n">lastResort</span> <span class="o">=</span> <span class="n">_defaultLastResort</span>

<span class="c1">#---------------------------------------------------------------------------</span>
<span class="c1">#   Manager classes and functions</span>
<span class="c1">#---------------------------------------------------------------------------</span>

<span class="k">class</span> <span class="nc">PlaceHolder</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    PlaceHolder instances are used in the Manager logger hierarchy to take</span>
<span class="sd">    the place of nodes for which no loggers have been defined. This class is</span>
<span class="sd">    intended for internal use only and not as part of the public API.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">alogger</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initialize with the specified logger being a child of this placeholder.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">loggerMap</span> <span class="o">=</span> <span class="p">{</span> <span class="n">alogger</span> <span class="p">:</span> <span class="kc">None</span> <span class="p">}</span>

    <span class="k">def</span> <span class="nf">append</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">alogger</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Add the specified logger as a child of this placeholder.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">alogger</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">loggerMap</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">loggerMap</span><span class="p">[</span><span class="n">alogger</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>

<span class="c1">#</span>
<span class="c1">#   Determine which class to use when instantiating loggers.</span>
<span class="c1">#</span>

<div class="viewcode-block" id="setLoggerClass"><a class="viewcode-back" href="../logging.html#logging.setLoggerClass">[文档]</a><span class="k">def</span> <span class="nf">setLoggerClass</span><span class="p">(</span><span class="n">klass</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Set the class to be used when instantiating a logger. The class should</span>
<span class="sd">    define __init__() such that only a name argument is required, and the</span>
<span class="sd">    __init__() should call Logger.__init__()</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">klass</span> <span class="o">!=</span> <span class="n">Logger</span><span class="p">:</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">klass</span><span class="p">,</span> <span class="n">Logger</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">&quot;logger not derived from logging.Logger: &quot;</span>
                            <span class="o">+</span> <span class="n">klass</span><span class="o">.</span><span class="vm">__name__</span><span class="p">)</span>
    <span class="k">global</span> <span class="n">_loggerClass</span>
    <span class="n">_loggerClass</span> <span class="o">=</span> <span class="n">klass</span></div>

<div class="viewcode-block" id="getLoggerClass"><a class="viewcode-back" href="../logging.html#logging.getLoggerClass">[文档]</a><span class="k">def</span> <span class="nf">getLoggerClass</span><span class="p">():</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Return the class to be used when instantiating a logger.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="n">_loggerClass</span></div>

<span class="k">class</span> <span class="nc">Manager</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    There is [under normal circumstances] just one Manager instance, which</span>
<span class="sd">    holds the hierarchy of loggers.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">rootnode</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initialize the manager with the root node of the logger hierarchy.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">root</span> <span class="o">=</span> <span class="n">rootnode</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">disable</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">emittedNoHandlerWarning</span> <span class="o">=</span> <span class="kc">False</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">loggerDict</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">loggerClass</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">logRecordFactory</span> <span class="o">=</span> <span class="kc">None</span>

    <span class="k">def</span> <span class="nf">getLogger</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get a logger with the specified name (channel name), creating it</span>
<span class="sd">        if it doesn&#39;t yet exist. This name is a dot-separated hierarchical</span>
<span class="sd">        name, such as &quot;a&quot;, &quot;a.b&quot;, &quot;a.b.c&quot; or similar.</span>

<span class="sd">        If a PlaceHolder existed for the specified name [i.e. the logger</span>
<span class="sd">        didn&#39;t exist but a child of it did], replace it with the created</span>
<span class="sd">        logger and fix up the parent/child references which pointed to the</span>
<span class="sd">        placeholder to now point to the logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">rv</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s1">&#39;A logger name must be a string&#39;</span><span class="p">)</span>
        <span class="n">_acquireLock</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">loggerDict</span><span class="p">:</span>
                <span class="n">rv</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">loggerDict</span><span class="p">[</span><span class="n">name</span><span class="p">]</span>
                <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">rv</span><span class="p">,</span> <span class="n">PlaceHolder</span><span class="p">):</span>
                    <span class="n">ph</span> <span class="o">=</span> <span class="n">rv</span>
                    <span class="n">rv</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">loggerClass</span> <span class="ow">or</span> <span class="n">_loggerClass</span><span class="p">)(</span><span class="n">name</span><span class="p">)</span>
                    <span class="n">rv</span><span class="o">.</span><span class="n">manager</span> <span class="o">=</span> <span class="bp">self</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">loggerDict</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">rv</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">_fixupChildren</span><span class="p">(</span><span class="n">ph</span><span class="p">,</span> <span class="n">rv</span><span class="p">)</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">_fixupParents</span><span class="p">(</span><span class="n">rv</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">rv</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">loggerClass</span> <span class="ow">or</span> <span class="n">_loggerClass</span><span class="p">)(</span><span class="n">name</span><span class="p">)</span>
                <span class="n">rv</span><span class="o">.</span><span class="n">manager</span> <span class="o">=</span> <span class="bp">self</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">loggerDict</span><span class="p">[</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">rv</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">_fixupParents</span><span class="p">(</span><span class="n">rv</span><span class="p">)</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="n">_releaseLock</span><span class="p">()</span>
        <span class="k">return</span> <span class="n">rv</span>

    <span class="k">def</span> <span class="nf">setLoggerClass</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">klass</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Set the class to be used when instantiating a logger with this Manager.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">klass</span> <span class="o">!=</span> <span class="n">Logger</span><span class="p">:</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">klass</span><span class="p">,</span> <span class="n">Logger</span><span class="p">):</span>
                <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">&quot;logger not derived from logging.Logger: &quot;</span>
                                <span class="o">+</span> <span class="n">klass</span><span class="o">.</span><span class="vm">__name__</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">loggerClass</span> <span class="o">=</span> <span class="n">klass</span>

    <span class="k">def</span> <span class="nf">setLogRecordFactory</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">factory</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Set the factory to be used when instantiating a log record with this</span>
<span class="sd">        Manager.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">logRecordFactory</span> <span class="o">=</span> <span class="n">factory</span>

    <span class="k">def</span> <span class="nf">_fixupParents</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">alogger</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Ensure that there are either loggers or placeholders all the way</span>
<span class="sd">        from the specified logger to the root of the logger hierarchy.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">name</span> <span class="o">=</span> <span class="n">alogger</span><span class="o">.</span><span class="n">name</span>
        <span class="n">i</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="n">rfind</span><span class="p">(</span><span class="s2">&quot;.&quot;</span><span class="p">)</span>
        <span class="n">rv</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="k">while</span> <span class="p">(</span><span class="n">i</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">rv</span><span class="p">:</span>
            <span class="n">substr</span> <span class="o">=</span> <span class="n">name</span><span class="p">[:</span><span class="n">i</span><span class="p">]</span>
            <span class="k">if</span> <span class="n">substr</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">loggerDict</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">loggerDict</span><span class="p">[</span><span class="n">substr</span><span class="p">]</span> <span class="o">=</span> <span class="n">PlaceHolder</span><span class="p">(</span><span class="n">alogger</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">obj</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">loggerDict</span><span class="p">[</span><span class="n">substr</span><span class="p">]</span>
                <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">Logger</span><span class="p">):</span>
                    <span class="n">rv</span> <span class="o">=</span> <span class="n">obj</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">PlaceHolder</span><span class="p">)</span>
                    <span class="n">obj</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">alogger</span><span class="p">)</span>
            <span class="n">i</span> <span class="o">=</span> <span class="n">name</span><span class="o">.</span><span class="n">rfind</span><span class="p">(</span><span class="s2">&quot;.&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">rv</span><span class="p">:</span>
            <span class="n">rv</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">root</span>
        <span class="n">alogger</span><span class="o">.</span><span class="n">parent</span> <span class="o">=</span> <span class="n">rv</span>

    <span class="k">def</span> <span class="nf">_fixupChildren</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ph</span><span class="p">,</span> <span class="n">alogger</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Ensure that children of the placeholder ph are connected to the</span>
<span class="sd">        specified logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">name</span> <span class="o">=</span> <span class="n">alogger</span><span class="o">.</span><span class="n">name</span>
        <span class="n">namelen</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
        <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">ph</span><span class="o">.</span><span class="n">loggerMap</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
            <span class="c1">#The if means ... if not c.parent.name.startswith(nm)</span>
            <span class="k">if</span> <span class="n">c</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">name</span><span class="p">[:</span><span class="n">namelen</span><span class="p">]</span> <span class="o">!=</span> <span class="n">name</span><span class="p">:</span>
                <span class="n">alogger</span><span class="o">.</span><span class="n">parent</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">parent</span>
                <span class="n">c</span><span class="o">.</span><span class="n">parent</span> <span class="o">=</span> <span class="n">alogger</span>

<span class="c1">#---------------------------------------------------------------------------</span>
<span class="c1">#   Logger classes and functions</span>
<span class="c1">#---------------------------------------------------------------------------</span>

<div class="viewcode-block" id="Logger"><a class="viewcode-back" href="../logging.html#logging.Logger">[文档]</a><span class="k">class</span> <span class="nc">Logger</span><span class="p">(</span><span class="n">Filterer</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Instances of the Logger class represent a single logging channel. A</span>
<span class="sd">    &quot;logging channel&quot; indicates an area of an application. Exactly how an</span>
<span class="sd">    &quot;area&quot; is defined is up to the application developer. Since an</span>
<span class="sd">    application can have any number of areas, logging channels are identified</span>
<span class="sd">    by a unique string. Application areas can be nested (e.g. an area</span>
<span class="sd">    of &quot;input processing&quot; might include sub-areas &quot;read CSV files&quot;, &quot;read</span>
<span class="sd">    XLS files&quot; and &quot;read Gnumeric files&quot;). To cater for this natural nesting,</span>
<span class="sd">    channel names are organized into a namespace hierarchy where levels are</span>
<span class="sd">    separated by periods, much like the Java or Python package namespace. So</span>
<span class="sd">    in the instance given above, channel names might be &quot;input&quot; for the upper</span>
<span class="sd">    level, and &quot;input.csv&quot;, &quot;input.xls&quot; and &quot;input.gnu&quot; for the sub-levels.</span>
<span class="sd">    There is no arbitrary limit to the depth of nesting.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">level</span><span class="o">=</span><span class="n">NOTSET</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initialize the logger with a name and an optional level.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">Filterer</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">level</span> <span class="o">=</span> <span class="n">_checkLevel</span><span class="p">(</span><span class="n">level</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">parent</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">propagate</span> <span class="o">=</span> <span class="kc">True</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">handlers</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span> <span class="o">=</span> <span class="kc">False</span>

<div class="viewcode-block" id="Logger.setLevel"><a class="viewcode-back" href="../logging.html#logging.Logger.setLevel">[文档]</a>    <span class="k">def</span> <span class="nf">setLevel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Set the logging level of this logger.  level must be an int or a str.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">level</span> <span class="o">=</span> <span class="n">_checkLevel</span><span class="p">(</span><span class="n">level</span><span class="p">)</span></div>

<div class="viewcode-block" id="Logger.debug"><a class="viewcode-back" href="../logging.html#logging.Logger.debug">[文档]</a>    <span class="k">def</span> <span class="nf">debug</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Log &#39;msg % args&#39; with severity &#39;DEBUG&#39;.</span>

<span class="sd">        To pass exception information, use the keyword argument exc_info with</span>
<span class="sd">        a true value, e.g.</span>

<span class="sd">        logger.debug(&quot;Houston, we have a %s&quot;, &quot;thorny problem&quot;, exc_info=1)</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">isEnabledFor</span><span class="p">(</span><span class="n">DEBUG</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_log</span><span class="p">(</span><span class="n">DEBUG</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="Logger.info"><a class="viewcode-back" href="../logging.html#logging.Logger.info">[文档]</a>    <span class="k">def</span> <span class="nf">info</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Log &#39;msg % args&#39; with severity &#39;INFO&#39;.</span>

<span class="sd">        To pass exception information, use the keyword argument exc_info with</span>
<span class="sd">        a true value, e.g.</span>

<span class="sd">        logger.info(&quot;Houston, we have a %s&quot;, &quot;interesting problem&quot;, exc_info=1)</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">isEnabledFor</span><span class="p">(</span><span class="n">INFO</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_log</span><span class="p">(</span><span class="n">INFO</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="Logger.warning"><a class="viewcode-back" href="../logging.html#logging.Logger.warning">[文档]</a>    <span class="k">def</span> <span class="nf">warning</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Log &#39;msg % args&#39; with severity &#39;WARNING&#39;.</span>

<span class="sd">        To pass exception information, use the keyword argument exc_info with</span>
<span class="sd">        a true value, e.g.</span>

<span class="sd">        logger.warning(&quot;Houston, we have a %s&quot;, &quot;bit of a problem&quot;, exc_info=1)</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">isEnabledFor</span><span class="p">(</span><span class="n">WARNING</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_log</span><span class="p">(</span><span class="n">WARNING</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="Logger.warn"><a class="viewcode-back" href="../logging.html#logging.Logger.warn">[文档]</a>    <span class="k">def</span> <span class="nf">warn</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s2">&quot;The &#39;warn&#39; method is deprecated, &quot;</span>
            <span class="s2">&quot;use &#39;warning&#39; instead&quot;</span><span class="p">,</span> <span class="ne">DeprecationWarning</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="Logger.error"><a class="viewcode-back" href="../logging.html#logging.Logger.error">[文档]</a>    <span class="k">def</span> <span class="nf">error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Log &#39;msg % args&#39; with severity &#39;ERROR&#39;.</span>

<span class="sd">        To pass exception information, use the keyword argument exc_info with</span>
<span class="sd">        a true value, e.g.</span>

<span class="sd">        logger.error(&quot;Houston, we have a %s&quot;, &quot;major problem&quot;, exc_info=1)</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">isEnabledFor</span><span class="p">(</span><span class="n">ERROR</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_log</span><span class="p">(</span><span class="n">ERROR</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="Logger.exception"><a class="viewcode-back" href="../logging.html#logging.Logger.exception">[文档]</a>    <span class="k">def</span> <span class="nf">exception</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Convenience method for logging an ERROR with exception information.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="n">exc_info</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="Logger.critical"><a class="viewcode-back" href="../logging.html#logging.Logger.critical">[文档]</a>    <span class="k">def</span> <span class="nf">critical</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Log &#39;msg % args&#39; with severity &#39;CRITICAL&#39;.</span>

<span class="sd">        To pass exception information, use the keyword argument exc_info with</span>
<span class="sd">        a true value, e.g.</span>

<span class="sd">        logger.critical(&quot;Houston, we have a %s&quot;, &quot;major disaster&quot;, exc_info=1)</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">isEnabledFor</span><span class="p">(</span><span class="n">CRITICAL</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_log</span><span class="p">(</span><span class="n">CRITICAL</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

    <span class="n">fatal</span> <span class="o">=</span> <span class="n">critical</span>

<div class="viewcode-block" id="Logger.log"><a class="viewcode-back" href="../logging.html#logging.Logger.log">[文档]</a>    <span class="k">def</span> <span class="nf">log</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Log &#39;msg % args&#39; with the integer severity &#39;level&#39;.</span>

<span class="sd">        To pass exception information, use the keyword argument exc_info with</span>
<span class="sd">        a true value, e.g.</span>

<span class="sd">        logger.log(level, &quot;We have a %s&quot;, &quot;mysterious problem&quot;, exc_info=1)</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">level</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
            <span class="k">if</span> <span class="n">raiseExceptions</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">&quot;level must be an integer&quot;</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">return</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">isEnabledFor</span><span class="p">(</span><span class="n">level</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_log</span><span class="p">(</span><span class="n">level</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="Logger.findCaller"><a class="viewcode-back" href="../logging.html#logging.Logger.findCaller">[文档]</a>    <span class="k">def</span> <span class="nf">findCaller</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stack_info</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Find the stack frame of the caller so that we can note the source</span>
<span class="sd">        file name, line number and function name.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">f</span> <span class="o">=</span> <span class="n">currentframe</span><span class="p">()</span>
        <span class="c1">#On some versions of IronPython, currentframe() returns None if</span>
        <span class="c1">#IronPython isn&#39;t run with -X:Frames.</span>
        <span class="k">if</span> <span class="n">f</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">f</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">f_back</span>
        <span class="n">rv</span> <span class="o">=</span> <span class="s2">&quot;(unknown file)&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&quot;(unknown function)&quot;</span><span class="p">,</span> <span class="kc">None</span>
        <span class="k">while</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s2">&quot;f_code&quot;</span><span class="p">):</span>
            <span class="n">co</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">f_code</span>
            <span class="n">filename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">normcase</span><span class="p">(</span><span class="n">co</span><span class="o">.</span><span class="n">co_filename</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">filename</span> <span class="o">==</span> <span class="n">_srcfile</span><span class="p">:</span>
                <span class="n">f</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">f_back</span>
                <span class="k">continue</span>
            <span class="n">sinfo</span> <span class="o">=</span> <span class="kc">None</span>
            <span class="k">if</span> <span class="n">stack_info</span><span class="p">:</span>
                <span class="n">sio</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">StringIO</span><span class="p">()</span>
                <span class="n">sio</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">&#39;Stack (most recent call last):</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
                <span class="n">traceback</span><span class="o">.</span><span class="n">print_stack</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sio</span><span class="p">)</span>
                <span class="n">sinfo</span> <span class="o">=</span> <span class="n">sio</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
                <span class="k">if</span> <span class="n">sinfo</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">:</span>
                    <span class="n">sinfo</span> <span class="o">=</span> <span class="n">sinfo</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
                <span class="n">sio</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
            <span class="n">rv</span> <span class="o">=</span> <span class="p">(</span><span class="n">co</span><span class="o">.</span><span class="n">co_filename</span><span class="p">,</span> <span class="n">f</span><span class="o">.</span><span class="n">f_lineno</span><span class="p">,</span> <span class="n">co</span><span class="o">.</span><span class="n">co_name</span><span class="p">,</span> <span class="n">sinfo</span><span class="p">)</span>
            <span class="k">break</span>
        <span class="k">return</span> <span class="n">rv</span></div>

<div class="viewcode-block" id="Logger.makeRecord"><a class="viewcode-back" href="../logging.html#logging.Logger.makeRecord">[文档]</a>    <span class="k">def</span> <span class="nf">makeRecord</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">level</span><span class="p">,</span> <span class="n">fn</span><span class="p">,</span> <span class="n">lno</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">exc_info</span><span class="p">,</span>
                   <span class="n">func</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">sinfo</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        A factory method which can be overridden in subclasses to create</span>
<span class="sd">        specialized LogRecords.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">rv</span> <span class="o">=</span> <span class="n">_logRecordFactory</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">level</span><span class="p">,</span> <span class="n">fn</span><span class="p">,</span> <span class="n">lno</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">exc_info</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span>
                             <span class="n">sinfo</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">extra</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">extra</span><span class="p">:</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">key</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">&quot;message&quot;</span><span class="p">,</span> <span class="s2">&quot;asctime&quot;</span><span class="p">])</span> <span class="ow">or</span> <span class="p">(</span><span class="n">key</span> <span class="ow">in</span> <span class="n">rv</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">):</span>
                    <span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="s2">&quot;Attempt to overwrite </span><span class="si">%r</span><span class="s2"> in LogRecord&quot;</span> <span class="o">%</span> <span class="n">key</span><span class="p">)</span>
                <span class="n">rv</span><span class="o">.</span><span class="vm">__dict__</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">extra</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
        <span class="k">return</span> <span class="n">rv</span></div>

    <span class="k">def</span> <span class="nf">_log</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">extra</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">stack_info</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Low-level logging routine which creates a LogRecord and then calls</span>
<span class="sd">        all the handlers of this logger to handle the record.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">sinfo</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="k">if</span> <span class="n">_srcfile</span><span class="p">:</span>
            <span class="c1">#IronPython doesn&#39;t track Python frames, so findCaller raises an</span>
            <span class="c1">#exception on some versions of IronPython. We trap it here so that</span>
            <span class="c1">#IronPython can use logging.</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="n">fn</span><span class="p">,</span> <span class="n">lno</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="n">sinfo</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">findCaller</span><span class="p">(</span><span class="n">stack_info</span><span class="p">)</span>
            <span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span> <span class="c1"># pragma: no cover</span>
                <span class="n">fn</span><span class="p">,</span> <span class="n">lno</span><span class="p">,</span> <span class="n">func</span> <span class="o">=</span> <span class="s2">&quot;(unknown file)&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&quot;(unknown function)&quot;</span>
        <span class="k">else</span><span class="p">:</span> <span class="c1"># pragma: no cover</span>
            <span class="n">fn</span><span class="p">,</span> <span class="n">lno</span><span class="p">,</span> <span class="n">func</span> <span class="o">=</span> <span class="s2">&quot;(unknown file)&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="s2">&quot;(unknown function)&quot;</span>
        <span class="k">if</span> <span class="n">exc_info</span><span class="p">:</span>
            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">exc_info</span><span class="p">,</span> <span class="ne">BaseException</span><span class="p">):</span>
                <span class="n">exc_info</span> <span class="o">=</span> <span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">exc_info</span><span class="p">),</span> <span class="n">exc_info</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">.</span><span class="n">__traceback__</span><span class="p">)</span>
            <span class="k">elif</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">exc_info</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">):</span>
                <span class="n">exc_info</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()</span>
        <span class="n">record</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">makeRecord</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">level</span><span class="p">,</span> <span class="n">fn</span><span class="p">,</span> <span class="n">lno</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span>
                                 <span class="n">exc_info</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="n">extra</span><span class="p">,</span> <span class="n">sinfo</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">handle</span><span class="p">(</span><span class="n">record</span><span class="p">)</span>

<div class="viewcode-block" id="Logger.handle"><a class="viewcode-back" href="../logging.html#logging.Logger.handle">[文档]</a>    <span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Call the handlers for the specified record.</span>

<span class="sd">        This method is used for unpickled records received from a socket, as</span>
<span class="sd">        well as those created locally. Logger-level filtering is applied.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="p">(</span><span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">disabled</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">record</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">callHandlers</span><span class="p">(</span><span class="n">record</span><span class="p">)</span></div>

<div class="viewcode-block" id="Logger.addHandler"><a class="viewcode-back" href="../logging.html#logging.Logger.addHandler">[文档]</a>    <span class="k">def</span> <span class="nf">addHandler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">hdlr</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Add the specified handler to this logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">_acquireLock</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">hdlr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">handlers</span><span class="p">):</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">hdlr</span><span class="p">)</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="n">_releaseLock</span><span class="p">()</span></div>

<div class="viewcode-block" id="Logger.removeHandler"><a class="viewcode-back" href="../logging.html#logging.Logger.removeHandler">[文档]</a>    <span class="k">def</span> <span class="nf">removeHandler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">hdlr</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Remove the specified handler from this logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">_acquireLock</span><span class="p">()</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">hdlr</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">handlers</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">hdlr</span><span class="p">)</span>
        <span class="k">finally</span><span class="p">:</span>
            <span class="n">_releaseLock</span><span class="p">()</span></div>

<div class="viewcode-block" id="Logger.hasHandlers"><a class="viewcode-back" href="../logging.html#logging.Logger.hasHandlers">[文档]</a>    <span class="k">def</span> <span class="nf">hasHandlers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        See if this logger has any handlers configured.</span>

<span class="sd">        Loop through all handlers for this logger and its parents in the</span>
<span class="sd">        logger hierarchy. Return True if a handler was found, else False.</span>
<span class="sd">        Stop searching up the hierarchy whenever a logger with the &quot;propagate&quot;</span>
<span class="sd">        attribute set to zero is found - that will be the last logger which</span>
<span class="sd">        is checked for the existence of handlers.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">c</span> <span class="o">=</span> <span class="bp">self</span>
        <span class="n">rv</span> <span class="o">=</span> <span class="kc">False</span>
        <span class="k">while</span> <span class="n">c</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">c</span><span class="o">.</span><span class="n">handlers</span><span class="p">:</span>
                <span class="n">rv</span> <span class="o">=</span> <span class="kc">True</span>
                <span class="k">break</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">c</span><span class="o">.</span><span class="n">propagate</span><span class="p">:</span>
                <span class="k">break</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">c</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">parent</span>
        <span class="k">return</span> <span class="n">rv</span></div>

<div class="viewcode-block" id="Logger.callHandlers"><a class="viewcode-back" href="../logging.html#logging.Logger.callHandlers">[文档]</a>    <span class="k">def</span> <span class="nf">callHandlers</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Pass a record to all relevant handlers.</span>

<span class="sd">        Loop through all handlers for this logger and its parents in the</span>
<span class="sd">        logger hierarchy. If no handler was found, output a one-off error</span>
<span class="sd">        message to sys.stderr. Stop searching up the hierarchy whenever a</span>
<span class="sd">        logger with the &quot;propagate&quot; attribute set to zero is found - that</span>
<span class="sd">        will be the last logger whose handlers are called.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">c</span> <span class="o">=</span> <span class="bp">self</span>
        <span class="n">found</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="k">while</span> <span class="n">c</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">hdlr</span> <span class="ow">in</span> <span class="n">c</span><span class="o">.</span><span class="n">handlers</span><span class="p">:</span>
                <span class="n">found</span> <span class="o">=</span> <span class="n">found</span> <span class="o">+</span> <span class="mi">1</span>
                <span class="k">if</span> <span class="n">record</span><span class="o">.</span><span class="n">levelno</span> <span class="o">&gt;=</span> <span class="n">hdlr</span><span class="o">.</span><span class="n">level</span><span class="p">:</span>
                    <span class="n">hdlr</span><span class="o">.</span><span class="n">handle</span><span class="p">(</span><span class="n">record</span><span class="p">)</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="n">c</span><span class="o">.</span><span class="n">propagate</span><span class="p">:</span>
                <span class="n">c</span> <span class="o">=</span> <span class="kc">None</span>    <span class="c1">#break out</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">c</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">parent</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">found</span> <span class="o">==</span> <span class="mi">0</span><span class="p">):</span>
            <span class="k">if</span> <span class="n">lastResort</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">record</span><span class="o">.</span><span class="n">levelno</span> <span class="o">&gt;=</span> <span class="n">lastResort</span><span class="o">.</span><span class="n">level</span><span class="p">:</span>
                    <span class="n">lastResort</span><span class="o">.</span><span class="n">handle</span><span class="p">(</span><span class="n">record</span><span class="p">)</span>
            <span class="k">elif</span> <span class="n">raiseExceptions</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">manager</span><span class="o">.</span><span class="n">emittedNoHandlerWarning</span><span class="p">:</span>
                <span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">&quot;No handlers could be found for logger&quot;</span>
                                 <span class="s2">&quot; </span><span class="se">\&quot;</span><span class="si">%s</span><span class="se">\&quot;\n</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">manager</span><span class="o">.</span><span class="n">emittedNoHandlerWarning</span> <span class="o">=</span> <span class="kc">True</span></div>

<div class="viewcode-block" id="Logger.getEffectiveLevel"><a class="viewcode-back" href="../logging.html#logging.Logger.getEffectiveLevel">[文档]</a>    <span class="k">def</span> <span class="nf">getEffectiveLevel</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get the effective level for this logger.</span>

<span class="sd">        Loop through this logger and its parents in the logger hierarchy,</span>
<span class="sd">        looking for a non-zero logging level. Return the first one found.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">logger</span> <span class="o">=</span> <span class="bp">self</span>
        <span class="k">while</span> <span class="n">logger</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">logger</span><span class="o">.</span><span class="n">level</span><span class="p">:</span>
                <span class="k">return</span> <span class="n">logger</span><span class="o">.</span><span class="n">level</span>
            <span class="n">logger</span> <span class="o">=</span> <span class="n">logger</span><span class="o">.</span><span class="n">parent</span>
        <span class="k">return</span> <span class="n">NOTSET</span></div>

<div class="viewcode-block" id="Logger.isEnabledFor"><a class="viewcode-back" href="../logging.html#logging.Logger.isEnabledFor">[文档]</a>    <span class="k">def</span> <span class="nf">isEnabledFor</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Is this logger enabled for level &#39;level&#39;?</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">manager</span><span class="o">.</span><span class="n">disable</span> <span class="o">&gt;=</span> <span class="n">level</span><span class="p">:</span>
            <span class="k">return</span> <span class="kc">False</span>
        <span class="k">return</span> <span class="n">level</span> <span class="o">&gt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">getEffectiveLevel</span><span class="p">()</span></div>

<div class="viewcode-block" id="Logger.getChild"><a class="viewcode-back" href="../logging.html#logging.Logger.getChild">[文档]</a>    <span class="k">def</span> <span class="nf">getChild</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">suffix</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get a logger which is a descendant to this one.</span>

<span class="sd">        This is a convenience method, such that</span>

<span class="sd">        logging.getLogger(&#39;abc&#39;).getChild(&#39;def.ghi&#39;)</span>

<span class="sd">        is the same as</span>

<span class="sd">        logging.getLogger(&#39;abc.def.ghi&#39;)</span>

<span class="sd">        It&#39;s useful, for example, when the parent logger is named using</span>
<span class="sd">        __name__ rather than a literal string.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">root</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">self</span><span class="p">:</span>
            <span class="n">suffix</span> <span class="o">=</span> <span class="s1">&#39;.&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">suffix</span><span class="p">))</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">manager</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="n">suffix</span><span class="p">)</span></div></div>

<span class="k">class</span> <span class="nc">RootLogger</span><span class="p">(</span><span class="n">Logger</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A root logger is not that different to any other logger, except that</span>
<span class="sd">    it must have a logging level and there is only one instance of it in</span>
<span class="sd">    the hierarchy.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initialize the logger with the name &quot;root&quot;.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">Logger</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;root&quot;</span><span class="p">,</span> <span class="n">level</span><span class="p">)</span>

<span class="n">_loggerClass</span> <span class="o">=</span> <span class="n">Logger</span>

<div class="viewcode-block" id="LoggerAdapter"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter">[文档]</a><span class="k">class</span> <span class="nc">LoggerAdapter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    An adapter for loggers which makes it easier to specify contextual</span>
<span class="sd">    information in logging output.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">logger</span><span class="p">,</span> <span class="n">extra</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Initialize the adapter with a logger and a dict-like object which</span>
<span class="sd">        provides contextual information. This constructor signature allows</span>
<span class="sd">        easy stacking of LoggerAdapters, if so desired.</span>

<span class="sd">        You can effectively pass keyword arguments as shown in the</span>
<span class="sd">        following example:</span>

<span class="sd">        adapter = LoggerAdapter(someLogger, dict(p1=v1, p2=&quot;v2&quot;))</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">logger</span> <span class="o">=</span> <span class="n">logger</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">extra</span> <span class="o">=</span> <span class="n">extra</span>

<div class="viewcode-block" id="LoggerAdapter.process"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.process">[文档]</a>    <span class="k">def</span> <span class="nf">process</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Process the logging message and keyword arguments passed in to</span>
<span class="sd">        a logging call to insert contextual information. You can either</span>
<span class="sd">        manipulate the message itself, the keyword args or both. Return</span>
<span class="sd">        the message and kwargs modified (or not) to suit your needs.</span>

<span class="sd">        Normally, you&#39;ll only need to override this one method in a</span>
<span class="sd">        LoggerAdapter subclass for your specific needs.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;extra&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">extra</span>
        <span class="k">return</span> <span class="n">msg</span><span class="p">,</span> <span class="n">kwargs</span></div>

    <span class="c1">#</span>
    <span class="c1"># Boilerplate convenience methods</span>
    <span class="c1">#</span>
<div class="viewcode-block" id="LoggerAdapter.debug"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.debug">[文档]</a>    <span class="k">def</span> <span class="nf">debug</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Delegate a debug call to the underlying logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">DEBUG</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="LoggerAdapter.info"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.info">[文档]</a>    <span class="k">def</span> <span class="nf">info</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Delegate an info call to the underlying logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">INFO</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="LoggerAdapter.warning"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.warning">[文档]</a>    <span class="k">def</span> <span class="nf">warning</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Delegate a warning call to the underlying logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">WARNING</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="LoggerAdapter.warn"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.warn">[文档]</a>    <span class="k">def</span> <span class="nf">warn</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s2">&quot;The &#39;warn&#39; method is deprecated, &quot;</span>
            <span class="s2">&quot;use &#39;warning&#39; instead&quot;</span><span class="p">,</span> <span class="ne">DeprecationWarning</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="LoggerAdapter.error"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.error">[文档]</a>    <span class="k">def</span> <span class="nf">error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Delegate an error call to the underlying logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">ERROR</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="LoggerAdapter.exception"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.exception">[文档]</a>    <span class="k">def</span> <span class="nf">exception</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Delegate an exception call to the underlying logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">ERROR</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="n">exc_info</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="LoggerAdapter.critical"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.critical">[文档]</a>    <span class="k">def</span> <span class="nf">critical</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Delegate a critical call to the underlying logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">CRITICAL</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="LoggerAdapter.log"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.log">[文档]</a>    <span class="k">def</span> <span class="nf">log</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Delegate a log call to the underlying logger, after adding</span>
<span class="sd">        contextual information from this adapter instance.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">isEnabledFor</span><span class="p">(</span><span class="n">level</span><span class="p">):</span>
            <span class="n">msg</span><span class="p">,</span> <span class="n">kwargs</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">process</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">_log</span><span class="p">(</span><span class="n">level</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="LoggerAdapter.isEnabledFor"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.isEnabledFor">[文档]</a>    <span class="k">def</span> <span class="nf">isEnabledFor</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Is this logger enabled for level &#39;level&#39;?</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">manager</span><span class="o">.</span><span class="n">disable</span> <span class="o">&gt;=</span> <span class="n">level</span><span class="p">:</span>
            <span class="k">return</span> <span class="kc">False</span>
        <span class="k">return</span> <span class="n">level</span> <span class="o">&gt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">getEffectiveLevel</span><span class="p">()</span></div>

<div class="viewcode-block" id="LoggerAdapter.setLevel"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.setLevel">[文档]</a>    <span class="k">def</span> <span class="nf">setLevel</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Set the specified level on the underlying logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">level</span><span class="p">)</span></div>

<div class="viewcode-block" id="LoggerAdapter.getEffectiveLevel"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.getEffectiveLevel">[文档]</a>    <span class="k">def</span> <span class="nf">getEffectiveLevel</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get the effective level for the underlying logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">getEffectiveLevel</span><span class="p">()</span></div>

<div class="viewcode-block" id="LoggerAdapter.hasHandlers"><a class="viewcode-back" href="../logging.html#logging.LoggerAdapter.hasHandlers">[文档]</a>    <span class="k">def</span> <span class="nf">hasHandlers</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        See if the underlying logger has any handlers.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">hasHandlers</span><span class="p">()</span></div></div>

<span class="n">root</span> <span class="o">=</span> <span class="n">RootLogger</span><span class="p">(</span><span class="n">WARNING</span><span class="p">)</span>
<span class="n">Logger</span><span class="o">.</span><span class="n">root</span> <span class="o">=</span> <span class="n">root</span>
<span class="n">Logger</span><span class="o">.</span><span class="n">manager</span> <span class="o">=</span> <span class="n">Manager</span><span class="p">(</span><span class="n">Logger</span><span class="o">.</span><span class="n">root</span><span class="p">)</span>

<span class="c1">#---------------------------------------------------------------------------</span>
<span class="c1"># Configuration classes and functions</span>
<span class="c1">#---------------------------------------------------------------------------</span>

<div class="viewcode-block" id="basicConfig"><a class="viewcode-back" href="../logging.html#logging.basicConfig">[文档]</a><span class="k">def</span> <span class="nf">basicConfig</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Do basic configuration for the logging system.</span>

<span class="sd">    This function does nothing if the root logger already has handlers</span>
<span class="sd">    configured. It is a convenience method intended for use by simple scripts</span>
<span class="sd">    to do one-shot configuration of the logging package.</span>

<span class="sd">    The default behaviour is to create a StreamHandler which writes to</span>
<span class="sd">    sys.stderr, set a formatter using the BASIC_FORMAT format string, and</span>
<span class="sd">    add the handler to the root logger.</span>

<span class="sd">    A number of optional keyword arguments may be specified, which can alter</span>
<span class="sd">    the default behaviour.</span>

<span class="sd">    filename  Specifies that a FileHandler be created, using the specified</span>
<span class="sd">              filename, rather than a StreamHandler.</span>
<span class="sd">    filemode  Specifies the mode to open the file, if filename is specified</span>
<span class="sd">              (if filemode is unspecified, it defaults to &#39;a&#39;).</span>
<span class="sd">    format    Use the specified format string for the handler.</span>
<span class="sd">    datefmt   Use the specified date/time format.</span>
<span class="sd">    style     If a format string is specified, use this to specify the</span>
<span class="sd">              type of format string (possible values &#39;%&#39;, &#39;{&#39;, &#39;$&#39;, for</span>
<span class="sd">              %-formatting, :meth:`str.format` and :class:`string.Template`</span>
<span class="sd">              - defaults to &#39;%&#39;).</span>
<span class="sd">    level     Set the root logger level to the specified level.</span>
<span class="sd">    stream    Use the specified stream to initialize the StreamHandler. Note</span>
<span class="sd">              that this argument is incompatible with &#39;filename&#39; - if both</span>
<span class="sd">              are present, &#39;stream&#39; is ignored.</span>
<span class="sd">    handlers  If specified, this should be an iterable of already created</span>
<span class="sd">              handlers, which will be added to the root handler. Any handler</span>
<span class="sd">              in the list which does not have a formatter assigned will be</span>
<span class="sd">              assigned the formatter created in this function.</span>

<span class="sd">    Note that you could specify a stream created using open(filename, mode)</span>
<span class="sd">    rather than passing the filename and mode in. However, it should be</span>
<span class="sd">    remembered that StreamHandler does not close its stream (since it may be</span>
<span class="sd">    using sys.stdout or sys.stderr), whereas FileHandler closes its stream</span>
<span class="sd">    when the handler is closed.</span>

<span class="sd">    .. versionchanged:: 3.2</span>
<span class="sd">       Added the ``style`` parameter.</span>

<span class="sd">    .. versionchanged:: 3.3</span>
<span class="sd">       Added the ``handlers`` parameter. A ``ValueError`` is now thrown for</span>
<span class="sd">       incompatible arguments (e.g. ``handlers`` specified together with</span>
<span class="sd">       ``filename``/``filemode``, or ``filename``/``filemode`` specified</span>
<span class="sd">       together with ``stream``, or ``handlers`` specified together with</span>
<span class="sd">       ``stream``.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="c1"># Add thread safety in case someone mistakenly calls</span>
    <span class="c1"># basicConfig() from multiple threads</span>
    <span class="n">_acquireLock</span><span class="p">()</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">handlers</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="n">handlers</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;handlers&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">handlers</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="k">if</span> <span class="s2">&quot;stream&quot;</span> <span class="ow">in</span> <span class="n">kwargs</span> <span class="ow">and</span> <span class="s2">&quot;filename&quot;</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;&#39;stream&#39; and &#39;filename&#39; should not be &quot;</span>
                                     <span class="s2">&quot;specified together&quot;</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">if</span> <span class="s2">&quot;stream&quot;</span> <span class="ow">in</span> <span class="n">kwargs</span> <span class="ow">or</span> <span class="s2">&quot;filename&quot;</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;&#39;stream&#39; or &#39;filename&#39; should not be &quot;</span>
                                     <span class="s2">&quot;specified together with &#39;handlers&#39;&quot;</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">handlers</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">filename</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;filename&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
                <span class="n">mode</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;filemode&quot;</span><span class="p">,</span> <span class="s1">&#39;a&#39;</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">filename</span><span class="p">:</span>
                    <span class="n">h</span> <span class="o">=</span> <span class="n">FileHandler</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">mode</span><span class="p">)</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="n">stream</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;stream&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
                    <span class="n">h</span> <span class="o">=</span> <span class="n">StreamHandler</span><span class="p">(</span><span class="n">stream</span><span class="p">)</span>
                <span class="n">handlers</span> <span class="o">=</span> <span class="p">[</span><span class="n">h</span><span class="p">]</span>
            <span class="n">dfs</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;datefmt&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
            <span class="n">style</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;style&quot;</span><span class="p">,</span> <span class="s1">&#39;%&#39;</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">style</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">_STYLES</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;Style must be one of: </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="s1">&#39;,&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
                                 <span class="n">_STYLES</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>
            <span class="n">fs</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;format&quot;</span><span class="p">,</span> <span class="n">_STYLES</span><span class="p">[</span><span class="n">style</span><span class="p">][</span><span class="mi">1</span><span class="p">])</span>
            <span class="n">fmt</span> <span class="o">=</span> <span class="n">Formatter</span><span class="p">(</span><span class="n">fs</span><span class="p">,</span> <span class="n">dfs</span><span class="p">,</span> <span class="n">style</span><span class="p">)</span>
            <span class="k">for</span> <span class="n">h</span> <span class="ow">in</span> <span class="n">handlers</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">h</span><span class="o">.</span><span class="n">formatter</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                    <span class="n">h</span><span class="o">.</span><span class="n">setFormatter</span><span class="p">(</span><span class="n">fmt</span><span class="p">)</span>
                <span class="n">root</span><span class="o">.</span><span class="n">addHandler</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
            <span class="n">level</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">&quot;level&quot;</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">level</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">root</span><span class="o">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">level</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">kwargs</span><span class="p">:</span>
                <span class="n">keys</span> <span class="o">=</span> <span class="s1">&#39;, &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">kwargs</span><span class="o">.</span><span class="n">keys</span><span class="p">())</span>
                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s1">&#39;Unrecognised argument(s): </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">keys</span><span class="p">)</span>
    <span class="k">finally</span><span class="p">:</span>
        <span class="n">_releaseLock</span><span class="p">()</span></div>

<span class="c1">#---------------------------------------------------------------------------</span>
<span class="c1"># Utility functions at module level.</span>
<span class="c1"># Basically delegate everything to the root logger.</span>
<span class="c1">#---------------------------------------------------------------------------</span>

<div class="viewcode-block" id="getLogger"><a class="viewcode-back" href="../logging.html#logging.getLogger">[文档]</a><span class="k">def</span> <span class="nf">getLogger</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Return a logger with the specified name, creating it if necessary.</span>

<span class="sd">    If no name is specified, return the root logger.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">name</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">Logger</span><span class="o">.</span><span class="n">manager</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">root</span></div>

<div class="viewcode-block" id="critical"><a class="viewcode-back" href="../logging.html#logging.critical">[文档]</a><span class="k">def</span> <span class="nf">critical</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Log a message with severity &#39;CRITICAL&#39; on the root logger. If the logger</span>
<span class="sd">    has no handlers, call basicConfig() to add a console handler with a</span>
<span class="sd">    pre-defined format.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">handlers</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">basicConfig</span><span class="p">()</span>
    <span class="n">root</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<span class="n">fatal</span> <span class="o">=</span> <span class="n">critical</span>

<div class="viewcode-block" id="error"><a class="viewcode-back" href="../logging.html#logging.error">[文档]</a><span class="k">def</span> <span class="nf">error</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Log a message with severity &#39;ERROR&#39; on the root logger. If the logger has</span>
<span class="sd">    no handlers, call basicConfig() to add a console handler with a pre-defined</span>
<span class="sd">    format.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">handlers</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">basicConfig</span><span class="p">()</span>
    <span class="n">root</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="exception"><a class="viewcode-back" href="../logging.html#logging.exception">[文档]</a><span class="k">def</span> <span class="nf">exception</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Log a message with severity &#39;ERROR&#39; on the root logger, with exception</span>
<span class="sd">    information. If the logger has no handlers, basicConfig() is called to add</span>
<span class="sd">    a console handler with a pre-defined format.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">error</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">exc_info</span><span class="o">=</span><span class="n">exc_info</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="warning"><a class="viewcode-back" href="../logging.html#logging.warning">[文档]</a><span class="k">def</span> <span class="nf">warning</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Log a message with severity &#39;WARNING&#39; on the root logger. If the logger has</span>
<span class="sd">    no handlers, call basicConfig() to add a console handler with a pre-defined</span>
<span class="sd">    format.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">handlers</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">basicConfig</span><span class="p">()</span>
    <span class="n">root</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="warn"><a class="viewcode-back" href="../logging.html#logging.warn">[文档]</a><span class="k">def</span> <span class="nf">warn</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s2">&quot;The &#39;warn&#39; function is deprecated, &quot;</span>
        <span class="s2">&quot;use &#39;warning&#39; instead&quot;</span><span class="p">,</span> <span class="ne">DeprecationWarning</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
    <span class="n">warning</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="info"><a class="viewcode-back" href="../logging.html#logging.info">[文档]</a><span class="k">def</span> <span class="nf">info</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Log a message with severity &#39;INFO&#39; on the root logger. If the logger has</span>
<span class="sd">    no handlers, call basicConfig() to add a console handler with a pre-defined</span>
<span class="sd">    format.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">handlers</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">basicConfig</span><span class="p">()</span>
    <span class="n">root</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="debug"><a class="viewcode-back" href="../logging.html#logging.debug">[文档]</a><span class="k">def</span> <span class="nf">debug</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Log a message with severity &#39;DEBUG&#39; on the root logger. If the logger has</span>
<span class="sd">    no handlers, call basicConfig() to add a console handler with a pre-defined</span>
<span class="sd">    format.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">handlers</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">basicConfig</span><span class="p">()</span>
    <span class="n">root</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="log"><a class="viewcode-back" href="../logging.html#logging.log">[文档]</a><span class="k">def</span> <span class="nf">log</span><span class="p">(</span><span class="n">level</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Log &#39;msg % args&#39; with the integer severity &#39;level&#39; on the root logger. If</span>
<span class="sd">    the logger has no handlers, call basicConfig() to add a console handler</span>
<span class="sd">    with a pre-defined format.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">root</span><span class="o">.</span><span class="n">handlers</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="n">basicConfig</span><span class="p">()</span>
    <span class="n">root</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">level</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="disable"><a class="viewcode-back" href="../logging.html#logging.disable">[文档]</a><span class="k">def</span> <span class="nf">disable</span><span class="p">(</span><span class="n">level</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Disable all logging calls of severity &#39;level&#39; and below.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="n">root</span><span class="o">.</span><span class="n">manager</span><span class="o">.</span><span class="n">disable</span> <span class="o">=</span> <span class="n">level</span></div>

<span class="k">def</span> <span class="nf">shutdown</span><span class="p">(</span><span class="n">handlerList</span><span class="o">=</span><span class="n">_handlerList</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Perform any cleanup actions in the logging system (e.g. flushing</span>
<span class="sd">    buffers).</span>

<span class="sd">    Should be called at application exit.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">for</span> <span class="n">wr</span> <span class="ow">in</span> <span class="nb">reversed</span><span class="p">(</span><span class="n">handlerList</span><span class="p">[:]):</span>
        <span class="c1">#errors might occur, for example, if files are locked</span>
        <span class="c1">#we just ignore them if raiseExceptions is not set</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="n">h</span> <span class="o">=</span> <span class="n">wr</span><span class="p">()</span>
            <span class="k">if</span> <span class="n">h</span><span class="p">:</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="n">h</span><span class="o">.</span><span class="n">acquire</span><span class="p">()</span>
                    <span class="n">h</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
                    <span class="n">h</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
                <span class="k">except</span> <span class="p">(</span><span class="ne">OSError</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">):</span>
                    <span class="c1"># Ignore errors which might be caused</span>
                    <span class="c1"># because handlers have been closed but</span>
                    <span class="c1"># references to them are still around at</span>
                    <span class="c1"># application exit.</span>
                    <span class="k">pass</span>
                <span class="k">finally</span><span class="p">:</span>
                    <span class="n">h</span><span class="o">.</span><span class="n">release</span><span class="p">()</span>
        <span class="k">except</span><span class="p">:</span> <span class="c1"># ignore everything, as we&#39;re shutting down</span>
            <span class="k">if</span> <span class="n">raiseExceptions</span><span class="p">:</span>
                <span class="k">raise</span>
            <span class="c1">#else, swallow</span>

<span class="c1">#Let&#39;s try and shutdown automatically on application exit...</span>
<span class="kn">import</span> <span class="nn">atexit</span>
<span class="n">atexit</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">shutdown</span><span class="p">)</span>

<span class="c1"># Null handler</span>

<div class="viewcode-block" id="NullHandler"><a class="viewcode-back" href="../logging.html#logging.NullHandler">[文档]</a><span class="k">class</span> <span class="nc">NullHandler</span><span class="p">(</span><span class="n">Handler</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    This handler does nothing. It&#39;s intended to be used to avoid the</span>
<span class="sd">    &quot;No handlers could be found for logger XXX&quot; one-off warning. This is</span>
<span class="sd">    important for library code, which may contain code to log events. If a user</span>
<span class="sd">    of the library does not configure logging, the one-off warning might be</span>
<span class="sd">    produced; to avoid this, the library developer simply needs to instantiate</span>
<span class="sd">    a NullHandler and add it to the top-level logger of the library module or</span>
<span class="sd">    package.</span>
<span class="sd">    &quot;&quot;&quot;</span>
<div class="viewcode-block" id="NullHandler.handle"><a class="viewcode-back" href="../logging.html#logging.NullHandler.handle">[文档]</a>    <span class="k">def</span> <span class="nf">handle</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Stub.&quot;&quot;&quot;</span></div>

<div class="viewcode-block" id="NullHandler.emit"><a class="viewcode-back" href="../logging.html#logging.NullHandler.emit">[文档]</a>    <span class="k">def</span> <span class="nf">emit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">record</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Stub.&quot;&quot;&quot;</span></div>

<div class="viewcode-block" id="NullHandler.createLock"><a class="viewcode-back" href="../logging.html#logging.NullHandler.createLock">[文档]</a>    <span class="k">def</span> <span class="nf">createLock</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">lock</span> <span class="o">=</span> <span class="kc">None</span></div></div>

<span class="c1"># Warnings integration</span>

<span class="n">_warnings_showwarning</span> <span class="o">=</span> <span class="kc">None</span>

<span class="k">def</span> <span class="nf">_showwarning</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">category</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">line</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Implementation of showwarnings which redirects to logging, which will first</span>
<span class="sd">    check to see if the file parameter is None. If a file is specified, it will</span>
<span class="sd">    delegate to the original warnings implementation of showwarning. Otherwise,</span>
<span class="sd">    it will call warnings.formatwarning and will log the resulting string to a</span>
<span class="sd">    warnings logger named &quot;py.warnings&quot; with level logging.WARNING.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">if</span> <span class="n">file</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">_warnings_showwarning</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">_warnings_showwarning</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">category</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">file</span><span class="p">,</span> <span class="n">line</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">s</span> <span class="o">=</span> <span class="n">warnings</span><span class="o">.</span><span class="n">formatwarning</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">category</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">line</span><span class="p">)</span>
        <span class="n">logger</span> <span class="o">=</span> <span class="n">getLogger</span><span class="p">(</span><span class="s2">&quot;py.warnings&quot;</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">logger</span><span class="o">.</span><span class="n">handlers</span><span class="p">:</span>
            <span class="n">logger</span><span class="o">.</span><span class="n">addHandler</span><span class="p">(</span><span class="n">NullHandler</span><span class="p">())</span>
        <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>

<div class="viewcode-block" id="captureWarnings"><a class="viewcode-back" href="../logging.html#logging.captureWarnings">[文档]</a><span class="k">def</span> <span class="nf">captureWarnings</span><span class="p">(</span><span class="n">capture</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    If capture is true, redirect all warnings to the logging package.</span>
<span class="sd">    If capture is False, ensure that warnings are not redirected to logging</span>
<span class="sd">    but to their original destinations.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">global</span> <span class="n">_warnings_showwarning</span>
    <span class="k">if</span> <span class="n">capture</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">_warnings_showwarning</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">_warnings_showwarning</span> <span class="o">=</span> <span class="n">warnings</span><span class="o">.</span><span class="n">showwarning</span>
            <span class="n">warnings</span><span class="o">.</span><span class="n">showwarning</span> <span class="o">=</span> <span class="n">_showwarning</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">_warnings_showwarning</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">warnings</span><span class="o">.</span><span class="n">showwarning</span> <span class="o">=</span> <span class="n">_warnings_showwarning</span>
            <span class="n">_warnings_showwarning</span> <span class="o">=</span> <span class="kc">None</span></div>
</pre></div>

           </div>
           
          </div>
          <footer>
  

  <hr/>

  <div role="contentinfo">
    <p>
        &copy; Copyright 2019, wzpan

    </p>
  </div>
  Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>. 

</footer>

        </div>
      </div>

    </section>

  </div>
  


  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>